多种型号的范围

时间:2013-01-23 15:08:55

标签: ruby-on-rails

我有几个对象都有approved字段。

在所有模型中实施范围的最佳方法是什么?

例如,我有一个sighting对象和一个comment对象。在向公众提供之前,他们都必须得到管理员的批准。

那么我怎样才能创建一个范围,分别返回comment.approvedsighting.approved而不在每个模型上重复它?这是关注的问题吗?

2 个答案:

答案 0 :(得分:12)

如果你只是想要范围界定功能,只是在每个模型中声明一个范围就好了。使用ActiveSupport::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.approvedComment.approved等来获取已批准记录的相应列表。您还可以使用unapprove方法,并可以执行Comment.approved.first.unapprove

之类的操作

在此示例中,我还添加了default_scope,这意味着Sighting.allComment.all等来电只会返回未经批准的项目。我将此作为示例包含在内,它可能不适用于您的实现。

答案 1 :(得分:0)

虽然我已经注意到从关注点中拉出的范围需要成为连接范围时的最后一个范围。我不太清楚为什么。

Comment.existing.approved

当我尝试它时:

Comment.approved.existing

它无声地失败了。

我接受了。我正在迁移旧代码并使用条件而不是lambdas。当我更换:条件时,范围顺序不再重要。

scope :existing, -> { where("real = 1") }

替换

scope :existing, :conditions => "real = 1"