I'm investigating on how validates_presence_of actually works. Suppose I have two models
class Project < ActiveRecord::Base
[...]
has_many :roles
end
and
class Role < ActiveRecord::Base
validates_presence_of :name, :project
belongs_to :project
end
I want it so that role always belongs to an existing project but I just found out from this example that this could lead to invalid (orphaned) roles saved into the db. So the right way to do that is to insert the validates_presence_of :project_id
in my Role model and it seems to work, even if I think that semantically has more sense to validate the presence of a project instead of a project id.
Besides that I was thinking that I could put an invalid id (for a non existing project) if I just validate the presence of project_id, since by default AR doesn't add integrity checks to migrations, and even if I add them manually some DB does not support them (i.e. MySQL with MyISAM or sqlite). This example prove that
# with validates_presence_of :name, :project, :project_id in the role class
Role.create!(:name => 'foo', :project_id => 1334, :project => Project.new)
AREL (0.4ms) INSERT INTO "roles" ("name", "project_id") VALUES ('foo', NULL)
+----+------+------------+
| id | name | project_id |
+----+------+------------+
| 7 | foo | |
+----+------+------------+
Of course I won't write code like this, but I want to prevent this kind of wrong data in DB.
I'm wondering how to ensure that a role ALWAYS has a (real and saved) project associated.
I found the validates_existence gem, but I prefer to not add a gem into my project unless is strictly necessary.
Any thought on this?
Update
validates_presence_of :project
and adding :null => false
for the project_id column in the migration seems to be a cleaner solution.