Область Rails 3 по умолчанию, область действия с переопределением

У меня есть ситуация, когда поведение существующего приложения меняется, и это вызывает у меня сильную головную боль.

Мое приложение имеет фотографии. Фотографии имеют статус: "batch", "queue", or "complete", Все существующие фотографии в приложении "завершены".

В 99% случаев мне нужно показывать только полные фотографии, а во всей существующей кодовой базе мне нужно, чтобы каждый вызов Photos ограничивался только полными фотографиями.

Однако на экранах, связанных с загрузкой и классификацией фотографий, мне нужно иметь возможность довольно легко переопределить эту область по умолчанию, чтобы показывать пакетные или поставленные в очередь фотографии.

Как и многим другим, мне нужно найти способ легко переопределить область по умолчанию в определенных ситуациях. Я посмотрел на эти вопросы ( 1, 2), и они, кажется, не отвечают тому, что я ищу.

Код, который я хотел бы работал, это:

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

Однако это не работает. Я попытался обернуть методы области видимости в лямбды, и это тоже не сработало.

Я понимаю, что default_scope поставляется с багажом, но если я не могу использовать его с переопределениями, я смотрю на добавление scope :complete ... и приходится прочесывать каждый вызов к фотографиям в моем существующем приложении и добавить .complete для того, чтобы отфильтровать необработанные фотографии.

Как бы вы решили эту проблему?

2 ответа

Решение

def self.batch
  Photo.unscoped.where(:status=>"batch")
end
Этот поток является более авторитетным: переопределение Rails default_scope

Я даю ему шанс. Допустим, вы хотите удалить предложение 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
Другие вопросы по тегам