You need to create two models using the generator. They look like this. After performing the migration and transition to the rails console, we must successfully execute the following commands :

project = Project.create title: "Мой проект" todo = Todo.create text: "Обсудить проект с женой" project.todos << todo 

Problem: I get RollBack on the second team and nothing happens

Class Code:

 class Project < ApplicationRecord has_many :todos end class Todo < ApplicationRecord belongs_to :project end 

Migration code:

 class CreateProjects < ActiveRecord::Migration[5.0] def change create_table :projects do |t| t.string :title t.timestamps end end end class CreateTodos < ActiveRecord::Migration[5.0] def change create_table :todos do |t| t.string :text t.boolean :isCompleted t.references :project, foreign_key: true t.timestamps end end end 

Which teams can generate models to make it work? Help me find errors, thanks!

  • And what exception gives? - Mal Skrylev
  • And even if you follow the agreement on the naming of characters in the rails, then avoid many pitfalls. - Mal Skrylev
  • @ MalKrylev case says, Rails relies heavily on naming conventions and in some places transforms itself between them, as a result there can be various surprises. CreateTodos migration (if you have applied it) and replace isCompleted with is_completed . - D-side

2 answers 2

 todo = Todo.create text: "Обсудить проект с женой" 

Yeah. Of course. You create this line Todo , not owned by Project 's.

And this contradicts:

 class Todo < ApplicationRecord belongs_to :project # <-- этой строчке end 

... t. since. with Rails 5, the belongs_to association belongs_to required , it is automatically validated, and if you don’t need it, it requires an explicit shutdown in this manner (but don’t do so, now I’ll explain why):

 class Todo < ApplicationRecord belongs_to :project, optional: true end 

But in your case it is not necessary, since your data model now does not imply the existence of tasks without projects. You just need not save the task until project_id appears in it. create saves it immediately.

You can set the project_id explicitly:

 todo = Todo.create(text: "Починить ассоциации", project_id: project.id) 

... but it makes an assumption about how the foreign key is called. This is a good place in the model, but since you follow the Rails conventions in this matter, it makes no sense to write in the model in plain text: Rails already knows. So what can be done simply:

 project.todos.create(text: "Починить ассоциации") 

Bonus: I would even teach the base to independently monitor this and refuse to record such things, even if validation for some reason will not be performed. Additional security measure. This is very easy, you just have to change the definition of one of the todos columns, making the presence of a value in the project_id mandatory:

 t.references :project, foreign_key: true, null: false # ^^^^^^^^^^^ NOT NULL в SQL 

    Tu already wrote the model by hand, why do you need to generate them there you have everything right. I am not familiar with the fifth rails, but you seem to want to write a link and save it in the database. Record of communication in base do approximately so:

    project = Project.new (name: "vjvjjjhjhjhbjh")

    todo = project.todos.create (text: "jvkvkghvjhbkjhlvg")