state_machine中状态的命名范围

时间:2011-11-20 04:02:30

标签: ruby-on-rails ruby state-machine

我在我的一个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

4 个答案:

答案 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)

我也需要此功能,但 state_machine 没有任何相似之处。虽然我发现了这个gist,但在这种情况下,aasm似乎是更好的状态机替代方案。

答案 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