Można zastąpić modele aasm_state Setter (lub stan w moim przykładzie), aby można było akceptować nazwy zdarzeń. Następnie sprawdzamy, czy jest to poprawne zdarzenie, a następnie sprawdzamy, czy przejście jest prawidłowe. Jeśli nie, dodajemy poprawny komunikat o błędzie.
Żądanie Spec
it "should cancel" do
put "/api/ampaigns/#{@campaign.id}", {campaign: {status: "cancel"}, format: :json}, valid_session
response.code.should == "204"
end
Model Spec
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
Model
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
pamiętać, że w tym przypadku nie może mieć przejścia ze stanu "X" do " opublikowane "i AASM zgłosi wyjątek. W przeciwnym razie brzmi rozsądnie. Chłopie, dziś rano jestem nitpicker: P – jaydel
W porządku, to jest pseudo-kod. Ma to jedynie na celu zilustrowanie ogólnego wzorca. – Wukerplank