Search code examples
ruby-on-railspolymorphic-associationsmodel-associations

rails has_many through and calling association in controller


When in my MechanicsController, the create action works, however, when I check the database, I notice that the taxi never gets a driver_id, I seem to never be able to get the taxi to contain both a mechanic_id and and driver_id at the same time and I'm not sure where I am going wrong.

Help would be much appreciated...

class Driver < ActiveRecord::Base
  has_many :taxis
  has_many :mechanics, :through => :taxis
end


class Mechanic < ActiveRecord::Base
  has_many :driver, :through => :taxis
  has_many :taxis
end


class Taxi < ActiveRecord::Base
  belongs_to    :driver
  belongs_to :mechanic
end

class MechanicsController < ApplicationController
  def create

    this_driver=Driver.find(params[:driver_id])
    @mechanic = this_driver.mechanics.new(params[:mechanic])
    @taxi=@mechanic.taxis.new(params[:queueprocessor])

    respond_to do |format|
      if @mechanic.save
        format.html { redirect_to @mechanic, notice: 'Mechanic was successfully created.' }
        format.json { render json: @mechanic, status: :created, location: @mechanic }
      else
        format.html { render action: "new" }
        format.json { render json: @mechanic.errors, status: :unprocessable_entity }
      end
    end
  end
end

And here are my migrations:

class CreateDrivers < ActiveRecord::Migration
  def change
    create_table :drivers do |t|
      t.timestamps
    end
  end
end


class CreateMechanics < ActiveRecord::Migration
  def change
    create_table :mechanics do |t|
      t.timestamps
    end
  end
end

class Taxis < ActiveRecord::Migration
  def change
    create_table :taxis do |t|
      t.belongs_to :driver
      t.belongs_to :mechanic
      t.timestamps
    end
  end
end

Thank you


Solution

  • There are a few things wrong here. Change this:

    class Mechanic < ActiveRecord::Base
      has_many :driver, :through => :taxis
      has_many :taxis
    end
    

    to this (note that :driver is changed to :drivers):

    class Mechanic < ActiveRecord::Base
      has_many :taxis
      has_many :drivers, :through => :taxis
    end
    

    Additionally, in the create action, you are attaching the models in the wrong sequence:

    this_driver=Driver.find(params[:driver_id])
    # this_driver.mechanics can't create a new association without a Taxi join model
    @mechanic = this_driver.mechanics.new(params[:mechanic])   
    @taxi=@mechanic.taxis.new(params[:queueprocessor])
    

    Should be changed to:

    this_driver=Driver.find(params[:driver_id])
    @taxi = this_driver.taxis.build(params[:queueprocessor])
    @mechanic = @taxi.build_mechanic(params[:mechanic])