使用嵌套属性创建对象时回滚

时间:2017-01-14 03:34:24

标签: ruby-on-rails nested-attributes rails-console cocoon-gem

我有这些模型,我正在使用带有nested_attributes的cocoon:

模型/ report.rb:

class Report < ApplicationRecord
  has_many :option_students

  accepts_nested_attributes_for :option_students, allow_destroy: true
end

模型/ option_students.rb:

class OptionStudent < ApplicationRecord
  belongs_to :student
  belongs_to :option
  belongs_to :report
end

我正在尝试使用rails console创建报告。我已经有一个学生和一个保存在DB上的选项。

如果我写:

Report.create(option_students_attributes: [{student_id: 1, option_id: 1}])

控制台输出回滚:

(0.2ms)  BEGIN
  Student Load (0.2ms)  SELECT  "students".* FROM "students" WHERE "students"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Option Load (0.1ms)  SELECT  "options".* FROM "options" WHERE "options"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  ROLLBACK

它不会创建报告,也不会创建option_student对象。

但如果我只输入Report.create然后我写

Report.update(1, option_students_attributes: [{student_id: 1, option_id: 1}])

更新报告时成功创建选项student。我做错了什么?我只是将嵌套属性与其他模型一起使用,并且有效。

1 个答案:

答案 0 :(得分:3)

我假设您使用的是rails 5,它默认需要更改belongs_to关系。从理论上讲,在保存嵌套属性时应该不会有问题,但由于在保存时(实际上:验证时)尚未设置report-id,因此保存将失败。这可以通过告诉rails关联如何相关来简单地解决:

has_many :option_students, inverse_of: :report

或者,您可以在optional类中添加OptionsStudent选项:

belongs_to :report, optional: true 

这不正确,它只是跳过验证,但也许它可能与其他两个关系相关 - 如果学生或选项并非总是需要。