Rails ActiveRecord ::验证关联存在的正确方法?

时间:2014-06-15 02:46:08

标签: ruby-on-rails activerecord activemodel

我在模型ProjectQueue之间建立了Rails关联。一个项目has_many队列。队列必须具有项目,因此在project_id上有存在验证

假设我想创建一个包含队列的新项目。例如,像这样:

project = Project.new(valid: param, options: here)
project.queues << Queue.new(other_valid: param, options: here)
project.save!

保存将失败,因为队列未通过project_id状态验证。

我通常难以理解的方法是创建一个项目,然后添加队列,并将整个数据包装在一个事务中,这样如果进程的任何部分失败,它就会回滚。 ......不知何故,这似乎比它应该更加丑陋。

那么,是否有更优雅的方法在新项目上创建队列而不需要进行状态验证,但是仍然断言这些队列必须有项目?

干杯

1 个答案:

答案 0 :(得分:2)

尝试在队列关联中使用build方法,如下所示:

project = Project.new(valid: param, options: here)
project.queues.build(other_valid: param, options: here) //this will build the queue and set its project_id to your current project.
project.save!

为了确保您的project_id具有正确的值,在调用project.save!之前插入此行:

project.queues.each do |queue|
  puts queue.project_id 
end

那你的代码有什么问题?

project = Project.new(valid: param, options: here) //build a new project - this is not yet persisted, so your id column is nil
project.queues << Queue.new(other_valid: param, options: here) // this line tries to save the queue to the database, does not wait for you to call project.save!
project.save!

致电时:

project.queues << Queue.new(other_valid: param, options: here)`

Rails尝试将新队列保存到数据库,但由于您的项目未保存,queue.project_id为零,因此您的队列验证失败。

如果您尝试使用从数据库中获取的项目(持久项目),您的代码将正常运行。

如果您仍想使用类似的东西,请在添加新队列之前保存项目,如下所示:

project = Project.new(valid: param, options: here)

if project.save
  project.queues << Queue.new(other_valid: param, options: here) //this guarantees that project_id exists
end