web-dev-qa-db-ja.com

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

AgentsCustomerモデルに追加するにはどうすればよいですか?

これが最善の方法ですか?

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テーブルにレコードを追加する方法について混乱していますか?

89
Mike

私はあなたが単にこれを行うことができると思います:

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

または、顧客の新しい家を作成する場合:

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

IDを使用して追加することもできます。

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

「最良の方法」は、あなたのニーズと最も快適に感じるものに依存します。混乱は、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

どちらの場合もAgentレコードを作成する必要があるため、@cust.houses.newHouse.newは実質的に同じであることに注意してください。

<<演算子

Mischaが言及しているように、コレクションで<<演算子を使用することもできます。これにより、Agentモデルのみが構築されます。Houseモデルを構築する必要があります。

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

createメソッド

createHouseAgentの両方のレコードを作成しますが、ビューまたはAPIに戻す場合はAgentモデルを見つける必要があります。

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

最後の注意として、houseを作成するときに例外を発生させる場合は、代わりにbang演算子を使用します(例:new!およびcreate!)。

72
IAmNaN

関連付けを追加するもう1つの方法は、外部キー列を使用することです。

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

または、正確な列名を使用して、レコードではなく関連するレコードのIDを渡します。

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