Reputation: 4792
I am using Ruby on Rails 3.2.9 and I am just trying to use the state_machine gem. I have following statements:
# Model class attributes are:
#
# [String] status
# [Boolean] checkin_1
# [Boolean] checkin_2
#
class Article < ActiveRecord::Base
state_machine :attribute => :status, :initial => :unconfirmed do
state :confirmed, :value => 'confirmed'
state :unconfirmed, :value => 'unconfirmed'
event :confirm do
transition :unconfirmed => :confirmed
end
event :unconfirm do
transition :confirmed => :unconfirmed
end
end
end
I would like to add custom validation messages to instance objects (avoiding to save those objects) when the confirm
event is triggered and checkin_1
and / or checkin_2
values are false
. That is, given I am trying to confirm
each of the following objects:
<#Article id: 1, :status: 'unconfirmed', checkin_1: false, checkin_2: false>
<#Article id: 1, :status: 'unconfirmed', checkin_1: false, checkin_2: true>
<#Article id: 1, :status: 'unconfirmed', checkin_1: true, checkin_2: false>
then I would like to avoid to save objects and to add respectively error messages as-like the following:
"can not be confirmed if it is not checked for 1 and 2"
"can not be confirmed if it is not checked for 1"
"can not be confirmed if it is not checked for 2"
How should I make that?
Upvotes: 4
Views: 276
Reputation: 4053
class Article < ActiveRecord::Base
attr_accessor :checkin_1
attr_accessor :checkin_2
state_machine :attribute => :status, :initial => :unconfirmed do
state :confirmed, :value => 'confirmed'
state :unconfirmed, :value => 'unconfirmed'
before_transition any => :confirm do |article|
return false unless article.custom_validate?
end
event :confirm do
transition :unconfirmed => :confirmed
end
event :unconfirm do
transition :confirmed => :unconfirmed
end
end
private
def custom_validate?
validate_flag = true
if self.checkin_1 and self.checkin_2
msg = "can not be confirmed if it is not checked for 1 and 2"
errors.add(:checkin_1, msg)
errors.add(:checkin_2, msg)
validate_flag = false
elsif !checkin_1
errors.add(:checkin_1, "can not be confirmed if it is not checked for 1")
validate_flag = false
elsif !checkin_2
errors.add(:checkin_2, "can not be confirmed if it is not checked for 2")
validate_flag = false
end
validate_flag
end
end
Upvotes: 0
Reputation: 5294
How about doing it like this:
state confirmed do
validate do
if !checkin_1 and !checkin_2
msg = "can not be confirmed if it is not checked for 1 and 2"
errors.add(:checkin_1, msg)
errors.add(:checkin_2, msg)
elsif !checkin_1
errors.add(:checkin_1, "can not be confirmed if it is not checked for 1")
elsif !checkin_2
errors.add(:checkin_2, "can not be confirmed if it is not checked for 2")
end
end
end
Upvotes: 1