Prevent orphan records

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:
http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_presence_of.

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
http://blog.hasmanythrough.com/2007/7/14/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.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs