Совсем недавно перешел на Rails 5.0.0.1 и не совсем понимаю кое-каких вещей, связанных с ассоциациями Active Record. Либо я что-то упускаю (давно не брался за рельсы).
В 4-ой версии рельс я мог спокойно проделать следующие действия, не получив при этом ни одной ошибки.
rails g model Parent name:string
rails g model Child name:string parent:references
rake db:migrate
rails c
Parent.create name: "Papa"
p = Parent.last
Child.create name: "Son"
c = Child.last
После этих нехитрых действий можно было спокойно производить следующие действия:
p.children << c # Добавить "Son" к "Papa"
p.children # Вывести список всех дочерних записей
c.parent # Посмотреть родителя c
c.parent = p # Напрямую установить родителя для c
Это все было довольно очевидно и удобно.
Но сейчас я обновился до 5-ой версии рельс и не совсем понимаю, что происходит.
Сначала я произвел стандартные операции:
rails g model Parent name:string
rails g model Child name:string parent:references
rails db:migrate
Ничего нового.
rails c
Parent.create name: "Papa"
p = Parent.last
Child.create name: "Son" # *
И в строке (*) я натыкаюсь на нечто. Что именно - точно сказать не могу. Конкретно происходит следующее:
(0.1ms) begin transaction
(0.1ms) rollback transaction
Судя по всему дело в том, что я не указал, к какому родителю относится потомок, потому как если сделать что-то типа
p.children.create name: "Son"
То тогда я уже никаких роллбэков не получаю и транзакция выполняется.
Собственно, вопрос: я что-то упускаю/делаю неправильно, или действительно больше нельзя создавать модель, которая является наследником другой модели, не указывая при этом родителя? И если это так, то есть ли какой-то способ вернуть прежнее поведение? Ведь может быть такая ситуация, что есть много дочерних моделей и много родителей, но не все дочерние используются. Как тогда их создавать?
Ответ
Во-первых, запустите последнюю команду с bang-методом create! вместо create - тогда в консоли увидите причину невыполнения операции:
p.children.create! name: "Son"
Во-вторых, вы верно предположили - в консоли вы увидите объяснение, что у объекта модели Child не указан обязательный параметр parent. Почему обязательный? Потому что в Rails 5 все связи belongs_to стали обязательными по-умолчанию.
В четвертых рельсах:
belongs_to :parent # по-умолчанию необязательная связь
belongs_to :parent, required: true # уточняем обязательность связи
В пятых рельсах:
belongs_to :parent # по-умолчанию обязательная связь
belongs_to :parent, optional: true # уточняем необязательность связи
Комментариев нет:
Отправить комментарий