2

特定のパラメーター (コード) がオブジェクト属性 (temporary_code) と一致する場合にのみ遷移を提供するには、state_machine イベントが必要です。

このコードをテストすると:

class User < ActiveRecord::Base

  def initialize
    @temporary_code = 'right'
  end

  state_machine :initial => :inactive do
    event :activate! do
      transition :inactive => :active, :if => lambda{ |code| code == @temporary_code }
    end

    state :inactive do
      def active?
        false
      end
    end

    state :active do
      def active?
        true
      end
    end
  end
end

しかし、どんなコードが与えられても遷移しません。以下の Rspec テストはエラーを返します。

describe "activation" do
  let(:user) { User.create }
  before { user.activate!('right') }
  specify { user.should be_active }
end

それの何が問題なのですか?

4

1 に答える 1

3

のようなインスタンス変数を参照すると、@temporary_codeまだ言及/定義/初期化されていなくても、常に結果が得られます。したがって、私が考えているのは、あなたが を参照@temporary_codeしていることですが、それは常に ですnil。割り当てられたラムダ:ifは User のインスタンスのコンテキストではなく、ステート マシンが入っているクラスのインスタンス内で実行されるためです。編集済み'。

今、あなたのコードには何か奇妙なことがあります:あなたは定義しました

transition :inactive => :active, :if => lambda {|code| code == @temporary_code}

しかし、ラムダに渡されるのは実際には currentuserです。そう

transition :inactive => :active, :if => lambda {|user| ... }

より適切でしょう。

私の知る限り、state_machine gem は、パラメーターに依存する遷移を作成する直接的な方法を提供していません。したがって、それを外に出して、 User クラスに次を追加する必要があると思います。

attr_accessor :temporary_code
attr_accessor :code

次に、トランジションを次のように変更します

transition :inactive => :active, 
           :if => lambda {|user| user.code == user.temporary_code}

activate!最初に呼び出すコードでtemporary_code.

于 2012-12-25T21:32:44.677 に答える