If I have
belongs_to :user
Do I need to have
validates_presence_of :user_id
?
Does Rails validate the presence of :user_id automatically if I have
belongs_to :user?
In other words, does Rails prevent against creating orphan records that
belong to non-existent users?
Thanks.
2009/7/4 Learn by Doing [email protected]:
Does Rails validate the presence of :user_id automatically if I have
belongs_to :user?
In other words, does Rails prevent against creating orphan records that
belong to non-existent users?
I believe rails will not stop you creating a record with an empty
user_id. To be pedantic this is ‘does not belong to any user’ rather
than ‘belongs to a non-existent user’ (for a non-existent user the
user_id would contain a non-nil value for which there is no user). In
some applications this is a valid requirement. If you wish to prevent
this then include validates_presence_of as you have indicated.
Colin
Colin L. wrote:
[…]
I believe rails will not stop you creating a record with an empty
user_id. To be pedantic this is ‘does not belong to any user’ rather
than ‘belongs to a non-existent user’ (for a non-existent user the
user_id would contain a non-nil value for which there is no user).
Correct.
In
some applications this is a valid requirement. If you wish to prevent
this then include validates_presence_of as you have indicated.
Also make the field not null in the DB and add a foreign key constraint
(the foreign_key_migrations and foreign_key_associations plugins make
this easy). Remember, Rails’ validations are not a replacement for the
DB’s integrity checks. Don’t rely solely on Rails for this.
Colin
Best,
Marnen Laibow-Koser
http://www.marnen.org
[email protected]
Thanks Marnen and Colin for your excellent suggestions.
Hi Colin,
After reading the API, I think that
validates_presence_of :user_id
will not even check to make sure that the user exists in the user
table. It only makes sure that the field value is not blank:
validates_presence_of (ActiveRecord::Validations::ClassMethods) - APIdock.
So this validation does not do the work of a proper foreign key
constraint. Am I reading the API incorrectly?
Thanks.
Jeffrey:
Thank you. I tried that but it still didn’t work. So I have this
class Stat < ActiveRecord::Base
belongs_to :user
validates_presence_of :user_id
validates_associated :user
The user table is empty. I then create a stat with user_id = 99, which
does not exist in the user table. No error is produced:
Loading development environment (Rails 2.3.2)
stat = Stat.new(:user_id => 99)
=> #<Stat id: nil, user_id: 99, …>
stat.save!
=> true
A new record with user_id = 99 was created in the database although the
associated user does not exist. Perhaps this validation only validates
the associated user when that user exists. See API:
http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates_associated
Did I read it right?
Thanks.
Quoting Learn By Doing [email protected]:
So this validation does not do the work of a proper foreign key
constraint. Am I reading the API incorrectly?
Yes, there is another validation to verify that the associated object
exists
and is valid, validates_associated.
HTH,
Jeffrey
There is nothing in rails that can validate an associated record
exists for a belongs_to relationship.
But you can use Josh S.'s fantastic validates_existence_of plugin
that does check whether the associated record exists or not
Check out his post here here
http://blog.hasmanythrough.com/2007/7/14/validate-your-existence
On Jul 5, 8:44 am, Learn by Doing [email protected]
Thanks nas. I am surprised that this has not made it to Rails 2.3.2.
nas wrote:
There is nothing in rails that can validate an associated record
exists for a belongs_to relationship.
But you can use Josh S.'s fantastic validates_existence_of plugin
that does check whether the associated record exists or not
Check out his post here here
has_many :through - Validate your existence
On Jul 5, 8:44�am, Learn by Doing [email protected]
I’ve found that:
validates_presence_of :user_id
validates_presence_of :user
works just fine.
From what I have been able to tell, validates_associated is meant for
when you are constructing two or more associated models at the same
time, and you don’t want to save them unless both validate. So your
user validates would contain:
validates_associated :address
which would run all the validations for the address model. However, you
can’t at the same time have a
validates_associated :user
line in the address model, because that will cause an infinite recursion
loop of validations.