Ответ 1
Мне также нужна эта функциональность, но state_machine не имеет ничего подобного. Хотя я нашел это gist, но aasm кажется лучшим вариантом альтернативы в данном случае.
Я использую state_machine с помощью ActiveRecord в одном из приложений Rails 3.1. Я нашел, что синтаксис для доступа к записям с разными состояниями является громоздким. Можно ли определить каждое состояние как область видимости одновременно, не указав вручную определения области?
Рассмотрим следующий пример:
class User < ActiveRecord:Base
state_machine :status, :initial => :foo do
state :foo
state :bar
# ...
end
end
# state_machine syntax:
User.with_status :foo
User.with_status :bar
# desired syntax:
User.foo
User.bar
Мне также нужна эта функциональность, но state_machine не имеет ничего подобного. Хотя я нашел это gist, но aasm кажется лучшим вариантом альтернативы в данном случае.
Я добавляю следующее к своим моделям:
state_machine.states.map do |state|
scope state.name, :conditions => { :state => state.name.to_s }
end
Не уверен, считаете ли вы это как "определение определений области видимости вручную?"
На всякий случай, если кто-то все еще ищет это, добавляются следующие методы при определении state_machine:
class Vehicle < ActiveRecord::Base
named_scope :with_states, lambda {|*states| {:conditions => {:state => states}}}
# with_states also aliased to with_state
named_scope :without_states, lambda {|*states| {:conditions => ['state NOT IN (?)', states]}}
# without_states also aliased to without_state
end
# to use this:
Vehicle.with_state(:parked)
Мне нравится использовать это, потому что никогда не будет конфликтов с именем состояния. Вы можете найти более подробную информацию на странице state_machine ActiveRecord.
Бонус в том, что он позволяет передавать массив, поэтому я часто делаю что-то вроде:
scope :cancelled, lambda { with_state([:cancelled_by_user, :cancelled_by_staff]) }
Я покажу вам способ, который можно использовать, если модель также имеет несколько state_machines.
Он работает даже в том случае, когда ваши состояния являются целыми числами.
def Yourmodel.generate_scopes_for_state_machines state_machines.each_pair do |machine_name, that_machine|
that_machine.states.map do |state|
# puts "will create these scopes: #{machine_name}_#{state.name} state: #{state.value} "
# puts "will create these scopes: #{machine_name}_#{state.name} state: #{state.name.to_s} "
# Price.scope "#{machine_name}_#{state.name}", :conditions => { machine_name => state.name.to_s }
Price.scope "#{machine_name}_#{state.name}", :conditions => { machine_name => state.value }
end end end
Yourmodel.generate_scopes_for_state_machines