Проверьте, попадает ли экземпляр модели в именованную область в rails
Предположим, что у меня есть именованная область:
class Foo < ActiveRecord::Base
named_scope :bar, :conditions => 'some_field = 1'
end
Это отлично работает для запросов, и у меня есть куча полезных named_scopes, определенных. Что я хотел бы иметь возможность сделать это:
f = Foo.find(:first)
f.some_field = 1
f.is_bar? #=> true
The '.бар? метод просто возвращает true или false, если экземпляр модели попадает в именованную область. Есть ли вообще возможность сделать это, не написав "is_bar_"?"метод, хотя я уже написал хороший способ проверить, есть ли что-то" is_bar_?- Если я правильно помню, сухой-это хорошо, так что любая помощь будет весьма признателен/
2 ответа:
Можно вызвать метод
exists?в именованной области, который будет запрашивать базу данных, чтобы увидеть, существует ли данная запись с этими условиями.Foo.bar.exists?(f)Однако это не будет работать, если вы изменили атрибуты на
fи не сохранили его в базе данных. Это происходит потому, что именованные условия области являются SQL, поэтому проверка должна происходить там. Попытка преобразования в Rubyifусловия является беспорядочной, особенно в более сложных сценариях.
Если ваши области просты, вы, вероятно, хотите избежать дублирования кода. Мое решение позволяет вызвать
model.active?, чтобы узнать, принадлежит ли экземпляр области, иModel.active, чтобы найти все записи, соответствующие области.model.active?не включает никаких запросов к базе данных.Подумайте о том, чтобы добавить это к
config/initializers/scope_and_method.rb:require 'active_record/named_scope' module ActiveRecord::NamedScope::ClassMethods def scope_and_method field, *values field = field.to_sym values.each do |value| named_scope value.to_sym, :conditions => {field => value} define_method "#{value}?" do send(field.to_sym) == value end end end endИспользование:
scope_and_method :state, 'active', 'inactive'Работает так, как если бы это было:
named_scope :active, :conditions => {:state => 'active'} named_scope :inactive, :conditions => {:state => 'inactive'} def active? state == 'active' end def inactive? state == 'inactive' endЭто решение для Rails 2.3. Это требует очень небольшой настройки для рельсов 3 и 4. (
named_scope->scope) я это проверю. скоро.