Pregunta cómo agregar registros a has_many: a través de la asociación en rieles


class Agents << ActiveRecord::Base
  belongs_to :customer
  belongs_to :house
end

class Customer << ActiveRecord::Base
  has_many :agents
  has_many :houses, through: :agents
end

class House << ActiveRecord::Base
  has_many :agents
  has_many :customers, through: :agents
end

¿Cómo agrego a la Agents modelo para Customer?

Es esta la mejor manera?

Customer.find(1).agents.create(customer_id: 1, house_id: 1)

Lo anterior funciona bien desde la consola, sin embargo, no sé cómo lograr esto en la aplicación real.

Imagine que se completa un formulario para el cliente que también toma house_id como entrada. Entonces, ¿hago lo siguiente en mi controlador?

def create 
  @customer = Customer.new(params[:customer])
  @customer.agents.create(customer_id: @customer.id, house_id: params[:house_id])
  @customer.save
end

En general, estoy confundido sobre cómo agregar registros en el has_many :through ¿mesa?


74
2017-09-04 04:01


origen


Respuestas:


Creo que simplemente puedes hacer esto:

 @cust = Customer.new(params[:customer])
 @cust.houses << House.find(params[:house_id])

O al crear una nueva casa para un cliente:

 @cust = Customer.new(params[:customer])
 @cust.houses.create(params[:house])

También puede agregar a través de los ids:

@cust.house_ids << House.find(params[:house_id])

129
2017-09-04 04:11



'La mejor manera' depende de sus necesidades y de lo que se sienta más cómodo. La confusión proviene de las diferencias del comportamiento de ActiveRecord del new y create métodos y el << operador.

los new Método

new no agregará un registro de asociación para usted. Tienes que construir el House y Agent graba tu mismo:

house = @cust.houses.new(params[:house])
house.save
agent = Agent(customer_id: @cust.id, house_id: house.id)
agent.save

Tenga en cuenta que @cust.houses.new y House.new son efectivamente iguales porque necesitas crear el Agent registro en ambos casos.

los << Operador

Como menciona Mischa, también puedes usar << operador en la colección. Esto solo construirá el Agent modelo para ti, debes construir el House modelo:

house = House.create(params[:house])
@cust.houses << house
agent = @cust.houses.find(house.id)

los create Método

create construirá ambos House y Agent registros para usted, pero tendrá que encontrar el Agent modelo si tiene la intención de devolverlo a su vista o api:

house = @cust.houses.create(params[:house])
agent = @cust.agents.where(house: house.id).first

Como nota final, si desea que se levanten excepciones al crear house use los operadores de bang en su lugar (p. new! y create!)


70
2017-08-07 21:55



Otra forma de agregar asociaciones es mediante el uso de las columnas de clave externa:

agent = Agent.new(...)
agent.house = House.find(...)
agent.customer = Customer.find(...)
agent.save

O use los nombres exactos de las columnas, pasando la ID del registro asociado en lugar del registro.

agent.house_id = house.id
agent.customer_id = customer.id

5
2018-01-29 18:52