我有这个类方法:
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
......但我在这里肯定是错误的,因为它根本不起作用。
感谢您的帮助。
答案 0 :(得分: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
如果你想实现这一点,你必须将next
移到def 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
答案 1 :(得分:2)
def next
default_column = self.class.default_column
User
.where("#{default_column} > ?", send(default_column))
.order("#{default_column} ASC")
.first
end