101 votes

comment ajouter des enregistrements à has_many: via une association dans des 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

Question Comment puis-je ajouter à l' Agents modèle Customer?

Est-ce la meilleure façon de faire?

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

Le ci-dessus fonctionne très bien à partir de la console cependant, je ne sais pas comment atteindre cet objectif dans l'application réelle.

Imaginez un formulaire est rempli par le client qui prend également house_id comme entrée. Puis je fais la suite dans mon contrôleur?

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

Dans l'ensemble je suis confus quant à la façon d'ajouter des enregistrements dans l' has_many :through tableau?

169voto

Mischa Points 26200

Je pense que vous pouvez simplement faire ceci:

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

Ou lors de la création d'une nouvelle maison pour un client:

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

82voto

IAmNaN Points 2713

"La meilleure façon" dépend de vos besoins et de ce qui se sent le plus à l'aise. La Confusion vient de différences ActiveRecord du comportement de l' new et create méthodes et l' << de l'opérateur.

L' new Méthode

new ne sera pas ajouter une association enregistrement pour vous. Vous avez à construire l' House et Agent dossiers vous-même:

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

Notez que @cust.houses.new et House.new sont effectivement les mêmes, car vous avez besoin pour créer l' Agent record dans les deux cas.

L' << De L'Opérateur

Comme Mischa mentionne, vous pouvez également utiliser l' << de l'opérateur sur la collection. Cela ne fera que renforcer l' Agent modèle pour vous, vous devez construire l' House modèle:

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

L' create Méthode

create va construire à la fois House et Agent des documents pour vous, mais vous aurez besoin de trouver l' Agent modèle si vous avez l'intention de retourner à votre vue ou de l'api:

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

Comme note finale, si vous voulez les exceptions soulevées lors de la création d' house utiliser le bang opérateurs de la place (par exemple, new! et create!).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X