ruby-on-rails - polimorficas - validaciones rails
cómo agregar registros a has_many: a través de la asociación en rieles (3)
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 al modelo de Agents
para el 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
tabla?
''La mejor manera'' depende de sus necesidades y de lo que se sienta más cómodo. La confusión proviene de las diferencias entre el comportamiento de ActiveRecord de los métodos new
y de la create
y el operador <<
.
El new
método
new
no agregará un registro de asociación para usted. Tienes que construir los registros de House
y Agent
tú 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 lo mismo porque necesita crear el registro del Agent
en ambos casos.
El <<
operador
Como menciona Mischa, también puede usar el operador <<
en la colección. Esto solo construirá el modelo de Agent
para ti, debes construir el modelo de la House
:
house = House.create(params[:house])
@cust.houses << house
agent = @cust.houses.find(house.id)
El método de create
create
creará los registros de House
y Agent
para usted, pero necesitará encontrar el modelo de Agent
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 una house
utilice los operadores de bang (por ejemplo, new!
Y create!
).
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])
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