Hello, I have a model Model:
SPECIAL_FEATURES = %w(none top)
class Model
validates_inclusion_of :special_feature, :in =>
Model::SPECIAL_FEATURES,
:on => :create, :message => "special_feature
%s is not defined"
belongs_to :team
def special_feature
attributes = attributes_before_type_cast
if attributes["special_feature"]
read_attribute(:special_feature).to_sym
else
nil
end
end
def special_feature=(value)
write_attribute(:special_feature, value.to_s)
end
end
In another class I do:
model = Model.new
model.special_feature = :none
model.save!
Then I got this error:
Validation failed: Special feature special_feature
{:model=>"Model", :attribute=>"Special feature", :value=>"none"} is
not defined (ActiveRecord::RecordInvalid)!
But I think it's defined... I've followed some tips to work with
enums, so it seems this is the way to work with them, but I'm doing
something wrong, any ideas?
Then I got this error:
Validation failed: Special feature special_feature
{:model=>"Model", :attribute=>"Special feature", :value=>"none"} is
not defined (ActiveRecord::RecordInvalid)!
I wonder if there's some confusion due to you assigning a symbol, but
checking for strings...
Try:
Well, I've just tested with "none" and 'none' and I've got the same
error.
I think symbol/string confusion is the problem, but not in that way.
Your setter method coerces everything to a string to clearly it
doesn't matter if you pass a string or a symbol to that. However your
getter method forces its return value to be a symbol, which your
validation then tries to compare to a string.
Fred
Gah! I didn't even look at the methods... why overload them? oh well,
I'm sure there's a perfectly valid reason</cynical disbelief>
So Eduardo, change the constant:
SPECIAL_FEATURES = [:none, :top]
...does that do it?
You might also want to change the setter:
def special_feature=(value)
write_attribute(:special_feature, value.to_s.to_sym)
end
Worth a bash... or better yet, I could fire up a console and check...
but I've gotta pack for a trip in the morning, so no time ATM
Thanks Michael, that was enough so it works now. I followed the tip to
emulate enums from this article (http://thinkinginrails.com/2010/04/
more-on-using-enums-for-constant-data-in-rails/), but it seems to have
a little mistake.