2012-12-25 1 views
2

주어진 매개 변수 (코드)가 객체 속성 (임시 코드)과 일치하는 경우에만 전환을 제공하려면 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 

무엇이 잘못 되었습니까?

답변

2

@temporary_code과 같은 인스턴스 변수를 참조 할 때 아직 정의/초기화되지 않았더라도 항상 결과를 얻습니다. 그래서 내가 생각하고있는 것은 @temporary_code을 참조하지만, :if에 할당 된 람다가 User 인스턴스의 컨텍스트에서 실행되지 않고 오히려 상태 시스템이 속한 클래스의 인스턴스 내에서 실행되기 때문에 항상 항상 nil입니다. '컴파일'되었습니다.

이제 코드에서 뭔가 이상한있다 : 당신이

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

를 정의하지만 람다에 전달되는 것은 사실 현재 user에있다. 따라서

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

이 더 적절합니다.

내가 아는 한 state_machine gem은 전환을 매개 변수에 의존하는 직접적인 방법을 제공하지 않습니다. 그래서 난 당신이 사용자 클래스에 다음과 같은 외부 가져 가서 추가해야한다고 생각 :

attr_accessor :temporary_code 
attr_accessor :code 

다음

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

로의 전환을 변경하고 activate! 먼저 temporary_code을 설정 호출하는 코드가 있습니다.

+0

답장을 보내 주셔서 감사합니다. 불행히도, 내가 사용할 때 \t 이벤트 활성화! ..., : if => 람다 {| 사용자 | ...} \t 그리고 매개 변수없이 호출하려고 user.activate (현재 개체를 가정하여이 정의에 의해 주어집니다)!() \t 내가 오류가 발생 매개 변수 "잘못된 번호 (1 0) ". (임시 해결 방안으로) 나는 activate 클래스 (bang 없음)를 추가하여 권한을 상위 레벨로 이동하기로 결정했습니다. 여기서 "activate!" 조건으로 불린다. 하지만 보안 구멍 때문에 나는 이상적인 방법이 아닙니다. 나는 피하려고 노력했습니다. : –

+0

설명하는 동작을 재현 할 수 없습니다. 단일 매개 변수를 사용하는 별도의'activate! '메서드를 정의한 것처럼 들립니다. – Confusion