как добавить записи в has many:через ассоциацию в rails
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
как добавить к Agents
модель Customer
?
это лучший способ?
Customer.find(1).agents.create(customer_id: 1, house_id: 1)
вышеуказанное отлично работает с консоли, однако я не знаю, как добиться этого в реальном приложении.
представьте, что для клиента заполняется форма, которая также принимает house_id
в качестве входных данных. Затем я делаю следующее в своем контроллере?
def create
@customer = Customer.new(params[:customer])
@customer.agents.create(customer_id: @customer.id, house_id: params[:house_id])
@customer.save
end
в целом я смущен тем, как добавлять записи в has_many :through
таблицы?
3 ответов
Я думаю, что вы можете просто сделать это:
@cust = Customer.new(params[:customer])
@cust.houses << House.find(params[:house_id])
или при создании нового дома для клиента:
@cust = Customer.new(params[:customer])
@cust.houses.create(params[:house])
вы также можете добавить через ids:
@cust.house_ids << House.find(params[:house_id])
"лучший способ" зависит от ваших потребностей и того, что чувствует себя наиболее комфортно. Путаница происходит от различий в поведении ActiveRecord new
и create
методы и <<
оператора.
на new
метод
new
не будет добавлять запись ассоциации для вас. Вы должны построить House
и Agent
записи себе:
house = @cust.houses.new(params[:house])
house.save
agent = Agent(customer_id: @cust.id, house_id: house.id)
agent.save
отметим, что @cust.houses.new
и House.new
фактически одинаковы, потому что вам нужно создать Agent
запись в обоих случаях.
на <<
оператор
как упоминает Миша, вы также можете использовать <<
оператор по сбору. Это будет только строить Agent
модель для вас, вы должны построить House
модель:
house = House.create(params[:house])
@cust.houses << house
agent = @cust.houses.find(house.id)
на create
метод
create
будут строить как House
и Agent
записи для вас, но вам нужно будет найти Agent
модель, если вы собираетесь вернуть это в свое представление или api:
house = @cust.houses.create(params[:house])
agent = @cust.agents.where(house: house.id).first
в качестве заключительного Примечания, если вы хотите, чтобы исключения были подняты при создании house
вместо этого используйте операторы взрыва (например,new!
и create!
).
другой способ добавить ассоциации-использовать столбцы внешнего ключа:
agent = Agent.new(...)
agent.house = House.find(...)
agent.customer = Customer.find(...)
agent.save
или используйте точные имена столбцов, передавая идентификатор связанной записи вместо записи.
agent.house_id = house.id
agent.customer_id = customer.id