在我的一个Rails模型中,我有这个:
class Project < ActiveRecord::Base
belongs_to :user
default_scope order("number ASC")
end
现在问题是我希望每个user
能够单独设置他或她default_scope
。例如,用户A可能想要default_scope order("date ASC")
,另一个人可能想要default_scope order("number DESC")
。
在我的User
表格中,我甚至还有用于存储这些值的列:order_column
和order_direction
。
但是如何让模型中的default_scope
动态化?
感谢您的帮助。
答案 0 :(得分:2)
您不想使用default_scope
。你做什么是常规scope
。
class Post < ActiveRecord::Base
scope :created_before, ->(time) { where("created_at < ?", time) }
end
答案 1 :(得分:2)
正如@screenmutt所说,默认范围并不是数据驱动的,它们是模型驱动的。由于此范围将根据每个用户的数据而变化,因此我会使用常规范围。
@fmendez答案非常好,但是它使用了默认范围,我刚才解释了为什么不推荐使用这种方法。
这就是我在你的案子中做的事情:
class Post < ActiveRecord::Base
scope :user_order, lambda { order("#{current_user.order_column} #{current_user.order_direction}")}
end
此处需要注意的一件非常重要的事情是 SQL注入:由于您在查询中嵌入了current_user.order_column
和current_user.order_direction
,因此必须确保用户只能使用有效数据将这些列提供到数据库中。否则,用户将能够编写不需要的SQL查询。
答案 2 :(得分:1)
你可以这样做:
def self.default_scope
order("#{current_user.order_column} #{current_user.order_direction}")
end
这应该动态选择存储在current_user的order_column
和order_direction
列中的值。
答案 3 :(得分:1)
您可以使用您需要的任何逻辑定义类方法,并将默认范围设置为该方法。类方法在返回关系时与命名范围相同,例如通过返回类似顺序的方法的结果。
例如:
def self.user_ordering
# user ording logic here
end
default_scope :user_ordering
您可能希望将current_user和current_user = class方法添加到User模型,该模型将请求用户维护在线程局部变量中。您通常会从应用程序控制器设置User模型上的当前用户。这使得current_user可用于所有模型的逻辑,例如排序顺序,并以线程安全的方式进行。