2017-05-30 4 views
0

Ich benutze Schienen 4.2.0 - das meine Modelle sind:Active: has_many und umfasst

class Customer < ApplicationRecord 
    has_many :meters, -> { includes :contracts } 
end 

class Meter < ApplicationRecord 
    belongs_to :customer 
    has_many :contracts 
end 

class Contract < ApplicationRecord 
    belongs_to :meter 
end 

Nun, ich möchte alle Verträge eines Kunden angezeigt werden soll. Nach dem Rails Guides sollte ich in der Lage sein, dies zu tun:

@customer.meters.contracts 

Allerdings funktioniert es nicht. Dies ist die Fehlermeldung:

undefined method `contracts' for #<Meter::ActiveRecord_Associations_CollectionProxy:0x007fb0385730b0> 

Was ist der beste Ansatz in dieser Situation? Danke für Ihre Hilfe!

Antwort

0

Jede Modellklasse, wie in Ihrem Beispiel, stellt nur eine dieser Instanzen eines Datenbankeintrags dar, d. H. Ihre Meter Klasse repräsentiert nur eine meter Zeile in der meters Tabelle. Also in diesem Sinne, können Sie sehen, dass die Erklärung, dass ein meter Instanzen hat viele contracts.

Lassen Sie uns diese Linie brechen: @customer.meters.contracts

Sie haben Ihre @customer Instanz und Sie fragen, es für alle seine Meter: @customer.meters. Die Rückgabe dieser meters Methode ist eine Sammlung von meters, die zu dieser @customer gehört. Da es sich um eine Instanz von meter handelt, die viele Verträge hat, können Sie die Erfassung von Zählern für ihre Verträge nicht auf diese Weise anfordern.

Sie können es von einem einzelnen Zähler fragen aber: @customer.meters.first.contracts oder Sie können über alle Meter laufen und alle Verträge erhalten:

@customer.meters.flat_map(&:contracts) # => an array of all the contracts 

Oder, allgemeiner, möchten Sie vielleicht eine Liste von ein anzuzeigen Kundenverträge in Aussicht:

<% @customer.meters.each do |meter| %> 
    <% meter.contracts.each do |contract| 
    // display the contract 
    <% end %> 
<% end %> 

Sie kann jedoch assoziieren alle contracts zu einem customer durch die meters Verein:

class Customer < ApplicationRecord 
    has_many :meters, -> { includes :contracts } 
    # ActiveRecord's shorthand declaration for associating 
    # records through a join table, in this case 'meters' 
    has_many :contracts, through: :meters 
end 

Durch das Hinzufügen, dass has_many X, through: Y Sie sagen, dass der Kundendatensatz, um Datensätze in einer anderen Tabelle X durch eine Join-Tabelle Y zugeordnet ist.

Damit ein customer mit bestehenden meters gegeben und diese Meter contracts bestehenden haben, werden Sie in der Lage sein @customer.contracts anrufen und Active die contracts durch den Beitritt des Kunden meters mit ihren contracts und geben die contracts Sammlung holen.

Mehr über die Rails Hat viele durch association: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Verwandte Themen