Why does Model.new in Rails 3 do an implicit conversion?
I'm facing a weird behavior in Rails 3 model instantiation.
So, I have a simple model :
class MyModel < ActiveRecord::Base
开发者_开发百科validates_format_of :val, :with => /^\d+$/, :message => 'Must be an integer value.'
end
Then a simple controller :
def create
@mod = MyModel.new(params[:my_model])
if @mod.save
...
end
end
first, params[:my_model].inspect
returns :
{:val => 'coucou :)'}
But after calling @mod = MyModel.new(params[:my_model])
...
Now, if I call @mod.val.inspect
I will get :
0
Why am I not getting the original string ?
At the end the validates succeed because val
is indeed an integer.
Is this because val
is defined as an integer in the database ?
How do I avoid this behavior and let the validation do his job ?
If val
is defined as an integer in your schema then calling @my_model.val
will always return an integer because AR does typecasting. That's not new to rails 3, it's always worked that way. If you want the original string value assigned in the controller, try @my_model.val_before_type_cast
. Note that validates_format_of
performs its validation on this pre-typecast value, so you don't need to specify that there.
EDIT
Sorry I was wrong about the "performs its validation on this pre-typecast value" part. Looking at the code of the validation, it calls .to_s
on the post-typecast value which in your case returns "0"
and therefore passes validation.
I'd suggest not bothering with this validation to be honest. If 0
is not a valid value for this column then validate that directly, otherwise just rely on the typecasting. If the user enters 123 foo
you'll end up with 123
in the database which is usually just fine.
There is also better fitting validator for your case:
http://guides.rubyonrails.org/active_record_validations_callbacks.html#validates_numericality_of
精彩评论