Home > Software design >  Rails: Migration for new has_many association
Rails: Migration for new has_many association

Time:05-14

I'm very new to Ruby and to Rails, So this is some kind of "Tell me what I'm doing wrong" question:

I've got a project with some existing ApplicationRecords. Now I like to add a new has_many association to one of them (called "Task").

has_many :assistants, class_name: "User"

I am providing the class name here as there is already another existing association has_many :users. (There can be 0-* assistants for every task.)

What is the right way to create the Migration for this? I've created the following:

class AddAssistantsToTask < ActiveRecord::Migration[6.1]
  def change
    add_reference :tasks, :assistant, null: true, foreign_key: {to_table: :users}, type: :uuid
  end
end

In the controller, I try to add Users to the assistant association:

if [email protected](@user)
    @task.assistants << @user
end

To this point it seems like everything is running as expected. When I try to query the added User using the Rails Console using

Task.find("some id").assistants.count

I get error messages, that the column users.task_id doesn't exist.

Thanks in advance for your help.

CodePudding user response:

You are doing the statement in the wrong direction

you have a task that has_many assistants, so the foreign_key should be on the assistant model, in this case Users

class AddAssistantsToTask < ActiveRecord::Migration[6.1]
  def change
    # Add foreign key assistant_id to users that points to tasks
    add_reference :users, :assistant, type: :uuid, null: true, foreign_key: { to_table: :tasks }
  end
end

Now you can see that the name assistant_id on table Users doesn't make sense, so I would rename to something like assisted_task or just task

class AddAssistantsToTask < ActiveRecord::Migration[6.1]
  def change
    # Add foreign key assistant_id to users that points to
    add_reference :users, :assisted_task, type: :uuid, null: true, foreign_key: { to_table: :tasks }
  end
end
has_many :assistants, class_name: "User", foreign_key: :assisted_task_id

or with task

class AddAssistantsToTask < ActiveRecord::Migration[6.1]
  def change
    # Add foreign key assistant_id to users that points to
    add_reference :users, :task, type: :uuid, null: true, foreign_key: true
  end
end
has_many :assistants, class_name: "User"

But I do agree with @BroiSatse, that this should be an many-to-many relation, because you are limiting each user to just have one task

  • Related