0

我有这个类方法:

def self.default_column
  "created_at"
end

如何重写以下函数,以便可以使用我的default_column方法?

def next
  User.where("created_at > ?", created_at).order('created_at ASC').first
end

我尝试过这样的事情......

def next
  User.where("#{default_column} > ?", default_column).order('#{default_column} ASC').first
end

...但我在这里一定是大错特错,因为它根本不起作用。

谢谢你的帮助。

4

2 回答 2

4

您可以使用:

def next
  User.where("#{User.default_column} > ?", self.send(User.default_column)).order("#{User.default_column} ASC").first
end

甚至更好

def next
  klass = self.class # This is supposing you are inside User model
  # Otherwise just use klass = User
  klass.where("#{klass.default_column} > ?", self.send(klass.default_column))
       .order(klass.arel_table[klass.default_column].asc)
end

请注意,如果您以这种方式处理该方法,则不能将其链接起来:例如User.where(name: 'something').next

如果你想实现这一点,你必须移动nextdef self.next在这种情况下,你必须将用户的实例传递给它,如下所示:

def self.next(user)
  klass = user.class
  klass.where("#{klass.default_column} > ?", user.send(klass.default_column))
       .order(klass.arel_table[klass.default_column].asc)
end

通过这种方式,您可以编写如下内容:User.where(name: 'test').next(@user). 您可以选择链接.first以直接获取结果,但这样您将无法链接其他内容,例如User.where(name: 'test').next(@user).where(email: 'my@mail.com')

最后,如果你想要纯 AREL(为了便携性)

def self.next(user)
  klass        = user.class
  arel         = klass.arel_table
  column       = klass.default_column # This helps cleaning up code
  column_value = user.send(column)

  klass.where(arel[column].gt(column_value))
       .order(arel[column].asc)
end
于 2013-07-16T14:58:11.583 回答
2
def next
  default_column = self.class.default_column
  User
  .where("#{default_column} > ?", send(default_column))
  .order("#{default_column} ASC")
  .first
end
于 2013-07-16T14:55:44.917 回答