Область 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