Я изучаю, как на самом деле работает validates_presence_of. Предположим, у меня есть две модели
class Project < ActiveRecord::Base
[...]
has_many :roles
end
и
class Role < ActiveRecord::Base
validates_presence_of :name, :project
belongs_to :project
end
Я хочу, чтобы роль всегда принадлежала существующему проекту, но я только что из этого примера обнаружил, что это может привести к тому, что недопустимые (потерянные) роли будут сохранены в БД. Поэтому правильный способ сделать это - вставить validates_presence_of :project_id
в мою ролевую модель, и, похоже, это сработает, даже если я думаю, что семантически имеет больше смысла проверять наличие проекта вместо идентификатора проекта.
Кроме того, я думал, что мог бы поставить недопустимый идентификатор (для несуществующего проекта), если бы я только проверял наличие project_id, так как по умолчанию AR не добавляет проверки целостности в миграции, и даже если я добавляю их вручную некоторые БД их не поддерживают (т.е. MySQL с MyISAM или sqlite). Этот пример доказывает, что
# 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 | |
+----+------+------------+
Конечно, я не буду писать такой код, но я хочу предотвратить неправильные данные в БД.
Мне интересно, как убедиться, что с ролью ВСЕГДА связан (реальный и сохраненный) проект.
Я нашел камень validates_existence , но я предпочитаю не добавлять камень в мой проект, если это не является строго необходимым.
Есть мысли по этому поводу?
Обновление
validates_presence_of :project
и добавление :null => false
для столбца project_id в миграции кажется более чистым решением.