7

我有一种情况,现有应用程序的行为正在发生变化,这让我很头疼。

我的应用程序有照片。照片有一个状态:"batch", "queue", or "complete"。应用程序中的所有现有照片都是“完整的”。

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

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

像许多其他人一样,我需要找到一种在某些情况下轻松覆盖默认范围的方法。我查看了这些问题(12),但它们似乎没有回答我正在寻找的内容。

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

class Photo < ActiveRecord::Base
  ...
  default_scope where(:status=>'complete')
  scope :batch, unscoped.where(:status=>'batch')
  scope :queue, unscoped.where(:status=>'queue')
  ...
end

但是,这是行不通的。我尝试将范围方法包装在 lambdas 中,但这也不起作用。

我意识到 default_scope 带有包袱,但如果我不能将它与覆盖一起使用,那么我正在考虑添加scope :complete ...并不得不梳理我现有应用程序中对照片的每次调用并添加.complete以过滤未处理的照片。

你将如何解决这个问题?

4

2 回答 2

6

def self.batch
  Photo.unscoped.where(:status=>"batch")
end
这个帖子比较权威: Overriding a Rails default_scope

于 2011-08-02T22:20:45.643 回答
3

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

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
于 2013-03-20T18:39:34.077 回答