我有几个对象都有一个approved
字段。
实现适用于所有模型的范围的最佳方法是什么?
例如,我有一个sighting
对象和一个comment
对象。在向公众提供之前,它们都必须得到管理员的批准。
那么如何创建一个既能返回又能分别返回的范围,comment.approved
而不sighting.approved
在每个模型上重复它呢?这就是担忧发挥作用的地方吗?
我有几个对象都有一个approved
字段。
实现适用于所有模型的范围的最佳方法是什么?
例如,我有一个sighting
对象和一个comment
对象。在向公众提供之前,它们都必须得到管理员的批准。
那么如何创建一个既能返回又能分别返回的范围,comment.approved
而不sighting.approved
在每个模型上重复它呢?这就是担忧发挥作用的地方吗?
如果您只想要范围功能,只需在每个模型中声明一个范围就可以了。如果您认为会发生这种情况,使用 anActiveSupport::Concern
将使您能够添加其他方法。这是一个例子:
# /app/models/concerns/approved.rb
module Approved
extend ActiveSupport::Concern
included do
default_scope { where(approved: false) }
scope :approved, -> { where(approved: true) }
end
def unapprove
update_attribute :approved, false
end
end
class Sighting < ActiveRecord::Base
include Approved
end
class Comment < ActiveRecord::Base
include Approved
end
然后,您可以拨打电话Sighting.approved
并Comment.approved
获取相应的批准记录列表。您还可以获得该unapprove
方法,并且可以执行类似Comment.approved.first.unapprove
.
在这个例子中,我还包括default_scope
了这意味着调用喜欢Sighting.all
或Comment.all
将只返回未经批准的项目。我将其作为示例包括在内,它可能不适用于您的实现。
虽然我注意到在连接范围时,从关注点中提取的范围必须是最后一个范围。我不太清楚为什么。
Comment.existing.approved
当我尝试它时:
Comment.approved.existing
它默默地失败了。
我收回了这一点。我正在迁移旧代码并使用带条件的范围而不是 lambda。当我替换 :conditions 时,范围顺序不再重要。
scope :existing, -> { where("real = 1") }
更换
scope :existing, :conditions => "real = 1"