state_machine中状态的命名范围

And*_*rew 10 ruby ruby-on-rails state-machine

我在我的一个Rails 3.1应用程序上使用带有ActiveRecord的state_machine.我发现访问具有不同状态的记录的语法很麻烦.是否可以在不编写范围定义的情况下同时将每个状态定义为范围?

考虑以下示例:

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
Run Code Online (Sandbox Code Playgroud)

Lar*_*eth 17

我将以下内容添加到我的模型中:

state_machine.states.map do |state|
  scope state.name, :conditions => { :state => state.name.to_s }
end
Run Code Online (Sandbox Code Playgroud)

不确定你是否将其视为"手工编写范围定义?"


Luc*_*cas 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)
Run Code Online (Sandbox Code Playgroud)

我喜欢使用它,因为永远不会与州名冲突.您可以在state_machine的ActiveRecord集成页面上找到更多信息.

奖金是它允许传递数组所以我经常做类似的事情:

scope :cancelled, lambda { with_state([:cancelled_by_user, :cancelled_by_staff]) }
Run Code Online (Sandbox Code Playgroud)


Zso*_*olt 3

我也需要这个功能,但是state_machine没有类似的功能。虽然我已经找到了这个要点,但在这种情况下aasm似乎是更好的状态机替代方案。