Проверьте, попадает ли экземпляр модели в именованную область в 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
) я это проверю. скоро.