我在我的一个Rails 3.1应用程序上使用state_machine和ActiveRecord。我发现访问具有不同状态的记录的语法很麻烦。是否可以在不编写范围定义的情况下同时将每个状态定义为范围?
请考虑以下示例:
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
答案 0 :(得分:16)
我将以下内容添加到我的模型中:
state_machine.states.map do |state|
scope state.name, :conditions => { :state => state.name.to_s }
end
不确定您是否将其视为“手写范围定义?”
答案 1 :(得分:8)
以防万一,如果有人还在寻找这个,那么在定义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's ActiveRecord integration page找到更多信息。
奖金是它允许传递数组所以我经常做类似的事情:
scope :cancelled, lambda { with_state([:cancelled_by_user, :cancelled_by_staff]) }
答案 2 :(得分:2)
答案 3 :(得分:0)
如果模型也有多个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