I have these models and I am using cocoon with nested_attributes:
models/report.rb:
class Report < ApplicationRecord
has_many :option_students
accepts_nested_attributes_for :option_students, allow_destroy: true
end
models/option_students.rb:
class OptionStudent < ApplicationRecord
belongs_to :student
belongs_to :option
belongs_to :report
end
I am trying to create a report using rails console. I already have a student and a option saved on DB.
If I write:
Report.create(option_students_attributes: [{student_id: 1, option_id: 1}])
The console outputs a rollback:
(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
It does not create the report nor the option_student object.
But if I just type Report.create
and then I write
Report.update(1, option_students_attributes: [{student_id: 1, option_id: 1}])
It successfully creates the option student when updating the report. What I am doing wrong with this? I just used nested attributes with other models and it worked.
I am assuming you are using rails 5, which changed the belongs_to
relation as by default required. Which theoretically when saving nested attributes should not be a problem, but because the report-id is not yet set when saving (actually: when validating), the save will fail. This can simply be cured by telling rails how associations are related:
has_many :option_students, inverse_of: :report
Alternatively you could add optional
option in the OptionsStudent
class:
belongs_to :report, optional: true
which is not as correct, it will just skip the validation, but maybe it could be relevant for the other two relations --if either the student or option is not always required.