Rails 3默认范围,带覆盖的范围

Rails 3 default scope, scope with override

我遇到的情况是现有应用程序的行为正在发生变化,这使我头疼不已。

我的应用包含照片。照片的状态为:"batch","queue", or"complete"。该应用程序中所有现有的照片均为"完整"。

99%的时间我只需要显示完整的照片,并且在所有现有的代码库中,我都要求对Photo的每次调用仅限于完整的照片。

但是,在与上传和分类照片有关的屏幕中,我需要能够相当容易地覆盖该默认范围,以显示批处理或排队的照片。

与其他许多实例一样,我需要找到一种在某些情况下可以轻松覆盖默认范围的方法。我看着这些问题(1、2),它们似乎并没有回答我在寻找什么。

我希望工作的代码是这样的:

1
2
3
4
5
6
7
class Photo < ActiveRecord::Base
  ...
  default_scope where(:status=>'complete')
  scope :batch, unscoped.where(:status=>'batch')
  scope :queue, unscoped.where(:status=>'queue')
  ...
end

但是,这不起作用。我尝试将范围方法package在lambda中,这也不起作用。

我意识到default_scope随身携带了行李,但是如果我不能将它与替换一起使用,那么我正在考虑添加scope :complete ...,并且必须梳理现有应用中对照片的每次调用并添加.complete为了过滤未处理的照片。

您将如何解决此问题?


1
2
3
def self.batch
  Photo.unscoped.where(:status=>"batch")
end

该线程更具权威性:覆盖Rails default_scope


我试一试。假设您想从默认范围中删除where子句(而不仅仅是用另一个值覆盖它)并保持关联,您可以尝试以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Photo < ActiveRecord::Base
  default_scope where(:status => 'complete').where(:deleted_at => '').order('id desc')

  def self.without_default_status
    # Get the ActiveRecord::Relation with the default_scope applied.
    photos = scoped.with_default_scope
    # Find the where clause that matches the where clause we want to remove
    # from the default scope and delete it.
    photos.where_values.delete_if { |query| query.to_sql ==""photos"."status" = 'complete'" }
    photos
  end

end