2011-07-05 6 views
7

जैसे रत्नों के लिए सबसे अच्छा अभ्यास मैं जानना चाहता हूं कि आप वर्कफ़्लो या एएएसएम मणि को नियंत्रक में कैसे उपयोग करते हैं यदि आप सभी विशेषताओं को अपडेट करना चाहते हैं, लेकिन वर्कफ़्लो/एएएसएम कॉलबैक को ठीक तरह से आग लगाना भी आवश्यक है।वर्कफ़्लो या एएएसएम

वर्तमान में, मैं इसे इस तरह का उपयोग करें:

class ModelController < ApplicationController 
    def update 
     @model = model.find(params[:id]) 

     if params[:application]['state'].present? 
     if params[:application]['state'] == "published" 
      @model.publish! 
     end 
     end 
     if @model.update_attributes(params[:application]); ... end 
    end 
    end 

कि सही महसूस नहीं करता है, क्या एक बेहतर समाधान हो सकता है?

उत्तर

0

यह एक छोटी सी चीज है, लेकिन यदि कोई चीज़ मौजूद नहीं है तो हैश रिटर्न शून्य है, तो आप उपस्थित होने के लिए कॉल को हटा सकते हैं?

मुझे एहसास है कि आप जो भी पूछ रहे हैं वह नहीं है। एक विकल्प मॉडल में पहले फ़िल्टर डालना है और वहां स्थिति के लिए अपनी जांच करना है। यह आपके नियंत्रक को आपकी स्थिति के अंतर्निहित भंडारण के लिए अंधेरा छोड़ देता है।

एक तरफ ध्यान दें पर, हम यहाँ AASM का उपयोग करें और मैं प्यार करता हूँ यह

3

:) मैं आम तौर पर कई कार्यों कि एक से दूसरे राज्य से संक्रमण को संभालने और स्पष्ट नाम है परिभाषित करते हैं।

def publish 
    # as the comment below states: your action 
    # will have to do some error catching and possibly 
    # redirecting; this goes only to illustrate my point 
    @story = Story.find(params[:id]) 
    if @story.may_publish? 
    @story.publish! 
    else 
    # Throw an error as transition is not legal 
    end 
end 

घोषित है कि आपके routes.rb में:

resources :stories do 
    member do 
    put :publish 
    end 
end 

अब आप अपने मार्ग को दर्शाता है कि वास्तव में क्या एक कहानी का क्या होता है: /stories/1234/publish

+0

ध्यान दें कि इस मामले में आप से राज्य में "x" के लिए "एक संक्रमण नहीं हो सकता प्रकाशित "और एएएसएम एक अपवाद उठाएगा। अन्यथा, उचित लगता है। लड़का, मैं आज सुबह एक नाइटपीकर हूं: पी – jaydel

+1

ठीक है, यह छद्म कोड है। यह केवल एक सामान्य पैटर्न को चित्रित करने के लिए है। – Wukerplank

0

मैं चाहता था आपके मामले में मैं तुम्हें एक publish कार्रवाई जोड़ने का सुझाव मेरा मॉडल अद्यतन होने के बाद नया राज्य लौटने के लिए, और यह सबसे आसान तरीका था जिसे मैं नियंत्रकों में बहुत से "वसा" के बिना ऐसा करने के लिए सोच सकता था, और यदि आपके वर्कफ़्लो में परिवर्तन होता है तो यह आगे बढ़ना आसान बनाता है:

class Article < ActiveRecord::Base 
    include Workflow 
    attr_accessible :workflow_state, :workflow_event # etc 
    validates_inclusion_of :workflow_event, in: %w(submit approve reject), allow_nil: true 
    after_validation :send_workflow_event 

    def workflow_event 
    @workflow_event 
    end 

    def workflow_event=(workflow_event) 
    @workflow_event = workflow_event 
    end 

    # this method should be private, normally, but I wanted to 
    # group the meaningful code together for this example 
    def send_workflow_event 
    if @workflow_event && self.send("can_#{@workflow_event}?") 
     self.send("#{@worklow_event}!") 
    end 
    end 

    # I pulled this from the workflow website, to use that example instead. 
    workflow do 
    state :new do 
     event :submit, :transitions_to => :awaiting_review 
    end 
    state :awaiting_review do 
     event :review, :transitions_to => :being_reviewed 
    end 
    state :being_reviewed do 
     event :accept, :transitions_to => :accepted 
     event :reject, :transitions_to => :rejected 
    end 
    state :accepted 
    state :rejected 
    end 
end 
2

आप मॉडल aasm_state setter (या मेरे उदाहरण में स्थिति) को ओवरराइड कर सकते हैं ताकि यह ईवेंट नाम स्वीकार कर सके। फिर हम यह देखने के लिए जांचते हैं कि यह एक वैध घटना है या नहीं, यह देखने के लिए जांचें कि संक्रमण वैध है या नहीं। यदि वे नहीं हैं तो हम सही त्रुटि संदेश जोड़ते हैं।

एक अनुरोध कल्पना

it "should cancel" do 
    put "/api/ampaigns/#{@campaign.id}", {campaign: {status: "cancel"}, format: :json}, valid_session 
    response.code.should == "204" 
end 

मॉडल युक्ति

it "should invoke the cancel method" do 
    campaign.update_attribute(:status, "cancel") 
    campaign.canceled?.should be_true 
end 
it "should add an error for illegal transition" do 
    campaign.update_attribute(:status, "complete") 
    campaign.errors.should include :status 
    campaign.errors[:status].should == ["status cannot transition from pending to complete"] 
end 
it "should add an error for invalid status type" do 
    campaign.update_attribute(:status, "foobar") 
    campaign.errors.should include :status 
    campaign.errors[:status].should == ["status of foobar is not valid. Legal values are pending, active, canceled, completed"] 
end 

मॉडल

class Campaign < ActiveRecord::Base 
    include AASM 
    aasm column: :status do 
    state :pending, :initial => true 
    state :active 
    state :canceled 
    state :completed 
    # Events 
    event :activate do 
     transitions from: :pending, to: :active 
    end 
    event :complete do 
     transitions from: :active, to: [:completed] 
    end 
    event :cancel do 
     transitions from: [:pending, :active], to: :canceled 
    end 
    end 
    def status=(value) 
    if self.class.method_defined?(value) 
     if self.send("may_#{value}?") 
     self.send(value) 
     else 
     errors.add(:status, "status cannot transition from #{status} to #{value}") 
     end 

    else 
     errors.add(:status, "status of #{value} is not valid. Legal values are #{aasm.states.map(&:name).join(", ")}") 
    end 
    end 
end 
संबंधित मुद्दे