Именованные области для состояний в state_machine - PullRequest
10 голосов
/ 20 ноября 2011

Я использую 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

Ответы [ 4 ]

16 голосов
/ 25 июля 2012

Я добавляю к своим моделям следующее:

state_machine.states.map do |state|
  scope state.name, :conditions => { :state => state.name.to_s }
end

Не уверен, если вы считаете это «написанием определений области вручную?»

8 голосов
/ 28 февраля 2013

На всякий случай, если кто-то все еще ищет это, при определении 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]) }
2 голосов
/ 19 февраля 2012

Мне также нужна была эта функциональность, но state_machine не имеет ничего подобного. Хотя я нашел это gist , но aasm в данном случае кажется лучшей альтернативой конечного автомата.

0 голосов
/ 23 июля 2013

Я покажу вам способ, который можно использовать, если модель также имеет несколько 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...