Recently I switched to Rails 5.0.0.1 and I don’t quite understand some of the things associated with Active Record associations. Or I’m missing something (I haven’t taken the rails for a long time).

In the 4th version of the rail, I could safely do the following steps without receiving a single error.

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 

After these simple actions, you could safely perform the following actions:

 p.children << c # Добавить "Son" к "Papa" p.children # Вывести список всех дочерних записей c.parent # Посмотреть родителя c c.parent = p # Напрямую установить родителя для c 

It was all pretty obvious and convenient.

But now I have updated to the 5th version of the rail and do not quite understand what is happening.

First, I performed the standard operations:

 rails g model Parent name:string rails g model Child name:string parent:references rails db:migrate 

Nothing new.

rails c

 Parent.create name: "Papa" p = Parent.last Child.create name: "Son" # * 

And in line (*) I stumble upon something . What exactly - I can not say for sure. Specifically, the following happens:

(0.1ms) begin transaction

(0.1ms) rollback transaction

Apparently, the fact is that I did not indicate to which parent the offspring belong, because if you do something like

 p.children.create name: "Son" 

Then I don’t receive any rollbacks and the transaction is executed.

Actually, the question is: am I missing / doing something wrong, or is it really no longer possible to create a model that is the heir to another model, without indicating the parent? And if so, is there any way to restore the previous behavior? After all, it may be that there are many child models and many parents, but not all child models are used. How then to create them?

  • Of course, the question in question concerns the association has_many - belongs_to, as with the others - did not check, but I'm sure the situation is the same. - smellyshovel
  • And the casket just opened: Child.create(name: "Son").errors.messages => {:parent=>["must exist"]} - D-side
  • @ D-side Yes, I forgot something about the bang-methods. I just switched to the frontend for a while. I rush between two fires, constantly something flies out of my head: D - smellyshovel
  • In, you have found another way to find out about the problem. You can, when you want :) - D-side
  • @ D-side is still usually easier to consult a professional like you get. Well, yes, of course, I myself immediately look for a solution. - smellyshovel

1 answer 1

First, run the last command with the bang method create! instead of create - then in the console you will see the reason for the failure to perform the operation:

 p.children.create! name: "Son" 

Secondly, you correctly assumed that in the console you will see an explanation that the required model parent parameter is not specified for the Child model object. Why mandatory? Because in Rails 5, all belongs_to links belongs_to become mandatory by default.

In the fourth rails:

 belongs_to :parent # по-умолчанию необязательная связь belongs_to :parent, required: true # уточняем обязательность связи 

Fifth rails:

 belongs_to :parent # по-умолчанию обязательная связь belongs_to :parent, optional: true # уточняем необязательность связи 
  • It means not for nothing that I sinned on innovations in the rails themselves :) Well, thanks! By the way, since I’m talking about innovations, don’t tell me where you can dig up information about everything new that you’ve added (deleted) in fifth rails? - smellyshovel
  • Thank you, it will be necessary to read. Thanks again for the explanation. - smellyshovel