問題
以下の 2 つのモデルが存在するとします。
app/models/lesson.rb
class Lesson < ApplicationRecord
has_many :lesson_schedules, dependent: :destroy
accepts_nested_attributes_for :lesson_schedules, reject_if: :all_blank, allow_destroy: true
end
app/models/lesson_schedule.rb
class LessonSchedule < ApplicationRecord
belongs_to :lesson
end
accepts_nested_attributes_for :lesson_schedules
の宣言により、Lesson
とそれに紐づく LessonSchedule
を次のコードで同時に作成することができます。
lesson =
Lesson.create(
title: '仏像彫刻',
lesson_schedules_attributes: [
{ wday: 0, start_time: '13:00', end_time: '17:30' },
{ wday: 3, start_time: '19:00', end_time: '21:00' }
]
)
lesson.persisted? #=> true
lesson.lesson_schedules.count #=> 2
だがしかし、Lesson
モデルで has_many :lesson_schedules
に scope を指定すると…
class Lesson < ApplicationRecord
# has_many の第 2 引数に scope を渡すようにした。
has_many :lesson_schedules, -> { order(:wday, :start_time, :end_time) }, dependent: :destroy
accepts_nested_attributes_for :lesson_schedules, reject_if: :all_blank, allow_destroy: true
end
lesson =
Lesson.create(
title: '仏像彫刻',
lesson_schedules_attributes: [
{ wday: 0, start_time: '13:00', end_time: '17:30' },
{ wday: 3, start_time: '19:00', end_time: '21:00' }
]
)
lesson.persisted? #=> false
lesson.errors.full_messages #=> ["Lesson schedules lesson must exist"]
作成できなくなりました。エラーメッセージを確認すると、どうやら LessonSchedule
の外部キーが設定できていないようです
解決策
has_many
や belongs_to
で inverse_of
オプションを使います。
app/models/lesson.rb
class Lesson < ApplicationRecord
has_many :lesson_schedules, -> { order(:wday, :start_time, :end_time) },
inverse_of: :lesson, dependent: :destroy
accepts_nested_attributes_for :lesson_schedules, reject_if: :all_blank, allow_destroy: true
end
app/models/lesson_schedule.rb
class LessonSchedule < ApplicationRecord
belongs_to :lesson, inverse_of: :lesson_schedules
end
こうすると Lesson.create
が再び成功するようになりました