如何将记录添加到has_many:通过rails中的关联

Mik*_*ike 91 activerecord ruby-on-rails has-many-through

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
Run Code Online (Sandbox Code Playgroud)

如何添加Agents模型Customer

这是最好的方法吗?

Customer.find(1).agents.create(customer_id: 1, house_id: 1)
Run Code Online (Sandbox Code Playgroud)

以上工作正常从控制台,但我不知道如何在实际应用程序中实现这一点.

想象一下,为客户填写的表格也house_id作为输入.然后在我的控制器中执行以下操作?

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

总的来说,我对如何在has_many :through表中添加记录感到困惑?

Mis*_*cha 150

我想你可以这样做:

 @cust = Customer.new(params[:customer])
 @cust.houses << House.find(params[:house_id])
Run Code Online (Sandbox Code Playgroud)

或者为客户创建新房子时:

 @cust = Customer.new(params[:customer])
 @cust.houses.create(params[:house])
Run Code Online (Sandbox Code Playgroud)

您还可以通过ID添加:

@cust.house_ids << House.find(params[:house_id])
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考:除非已保存父级,否则无法创建关联的房屋. (14认同)

IAm*_*NaN 74

"最好的方式"取决于您的需求和最舒适的方式.混淆来自于ActiveRecord newcreate方法和<<运算符的差异.

new方法

new不会为您添加关联记录.您必须自己构建HouseAgent记录:

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

请注意,@cust.houses.new并且House.new实际上是相同的,因为您需要Agent在两种情况下都创建记录.

<<运营商

正如Mischa所提到的,您也可以<<在集合中使用运算符.这只会Agent为您构建模型,您必须构建House模型:

house = House.create(params[:house])
@cust.houses << house
agent = @cust.houses.find(house.id)
Run Code Online (Sandbox Code Playgroud)

create方法

create将为您构建两个HouseAgent记录,但Agent如果您打算将其返回到您的视图或api ,则需要找到该模型:

house = @cust.houses.create(params[:house])
agent = @cust.agents.where(house: house.id).first
Run Code Online (Sandbox Code Playgroud)

最后要注意的是,如果您希望在创建时house使用bang运算符来引发异常(例如new!create!).

  • 行`agent = @ cust.houses.find(house.id)`应该读`agent = @ cust.agents.find(house.id)`而不是?"新方法"中的"agent"变量与后面示例中的"agent"不同.可能会为在连接表上使用其他属性的人员造成一些混淆. (2认同)

Den*_*nis 5

添加关联的另一种方法是使用外键列:

agent = Agent.new(...)
agent.house = House.find(...)
agent.customer = Customer.find(...)
agent.save
Run Code Online (Sandbox Code Playgroud)

或者使用确切的列名称,传递相关记录的ID而不是记录.

agent.house_id = house.id
agent.customer_id = customer.id
Run Code Online (Sandbox Code Playgroud)