5

के साथ गतिशील प्रारंभिक राज्यों का परीक्षण करना मुझे StateMachine एस Factory Girl के साथ परीक्षण करने में कुछ समस्याएं आ रही हैं। ऐसा लगता है कि फैक्टरी गर्ल वस्तुओं को शुरू करने के तरीके से नीचे है।फैक्टरीगर्ल और स्टेटमाचिन

क्या मुझे कुछ याद आ रही है, या यह उतना आसान नहीं है जितना होना चाहिए?

class Car < ActiveRecord::Base 
    attr_accessor :stolen # This would be an ActiveRecord attribute 

    state_machine :initial => lambda { |object| object.stolen ? :moving : :parked } do 
    state :parked, :moving 
    end 
end 

Factory.define :car do |f| 
end 

तो, प्रारंभिक अवस्था stolen विशेषता आरंभीकरण के दौरान सेट है, इस पर निर्भर करता है।

Car.new(:stolen => true) 

## Broadly equivalent to 
car = Car.new do |c| 
    c.attributes = {:stolen => true} 
end 
car.initialize_state # StateMachine calls this at the end of the main initializer 
assert_equal car.state, 'moving' 

हालांकि क्योंकि फैक्टरी लड़की को व्यक्तिगत रूप से अपने ओवरराइड (factory_girl/proxy/build.rb देखें) सेट करने से पहले वस्तु initializes, इसका मतलब है कि प्रवाह है और अधिक की तरह:

यह ठीक काम करने के लिए, क्योंकि ActiveRecord अपने प्रारंभकर्ता के हिस्से के रूप गुण सेट लगता है
Factory(:car, :stolen => true) 

## Broadly equivalent to 
car = Car.new 
car.initialize_state # StateMachine calls this at the end of the main initializer 
car.stolen = true 
assert_equal car.state, 'moving' # Fails, because the car wasn't 'stolen' when the state was initialized 

उत्तर

3

तुम सिर्फ अपने कारखाने पर एक after_build कॉलबैक जोड़ने में सक्षम हो सकता है:

Factory.define :car do |c| 
    c.after_build { |car| car.initialize_state } 
end 

हालांकि, मुझे नहीं लगता कि आप shou एलडी इस तरह से अपने प्रारंभिक राज्य को स्थापित करने पर भरोसा करते हैं। ActiveRecord ऑब्जेक्ट्स का उपयोग करना बहुत आम है जैसे फैक्टरीगर्ल करता है (यानी सी = कार.net को कॉल करके; c.my_column = 123)।

मेरा सुझाव है कि आप अपने प्रारंभिक राज्य को शून्य होने दें। फिर राज्य को वांछित मूल्य पर सेट करने के लिए एक सक्रिय रिकॉर्ड कॉलबैक का उपयोग करें।

class Car < ActiveRecord::Base 
    attr_accessor :stolen # This would be an ActiveRecord attribute 

    state_machine do 
    state :parked, :moving 
    end 

    before_validation :set_initial_state, :on => :create 

    validates :state, :presence => true 

    private 
    def set_initial_state 
    self.state ||= stolen ? :moving : :parked 
    end 
end 

मुझे लगता है कि यह आपको अधिक अनुमानित परिणाम देगा।

एक चेतावनी यह है कि सहेजे गए कार ऑब्जेक्ट्स के साथ काम करना मुश्किल होगा क्योंकि राज्य अभी तक सेट नहीं होगा।

0

की कोशिश की phylae के जवाब में पाया गया कि नई FactoryGirl इस वाक्य को स्वीकार नहीं करता है, और after_build विधि ActiveRecord वस्तु पर मौजूद नहीं है। इस नए वाक्यविन्यास को काम करना चाहिए:

Factory.define 
    factory :car do 
    after(:build) do |car| 
     car.initialize_state 
    end 
    end 
end