Fields_for und Accepts_nested_attributes_for dazu bringen, mit einer Gehört_zu-Beziehung zu arbeiten
-
19-09-2019 - |
Frage
Ich kann anscheinend kein verschachteltes Formular in einer Rails-Ansicht für a generieren belongs_to
Beziehung mit dem Neuen accepts_nested_attributes_for
Einrichtung von Rails 2.3.Ich habe mir viele der verfügbaren Ressourcen angesehen und es sieht aus wie mein Code sollen arbeiten, aber fields_for
explodiert bei mir und ich vermute, dass es etwas damit zu tun hat, wie ich die verschachtelten Modelle konfiguriert habe.
Der Fehler, auf den ich stoße, ist ein häufiger Fehler, der viele Ursachen haben kann:
'@account[owner]' is not allowed as an instance variable name
Hier sind die beiden beteiligten Modelle:
class Account < ActiveRecord::Base
# Relationships
belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
accepts_nested_attributes_for :owner
has_many :users
end
class User < ActiveRecord::Base
belongs_to :account
end
Vielleicht mache ich es hier „rong“, da ein Konto einen „Eigentümer“ und möglicherweise „Benutzer“ haben kann, ein Benutzer jedoch nur ein „Konto“ hat, basierend auf dem Schlüssel „account_id“ des Benutzermodells.
Dies ist der Ansichtscode in new.html.haml, der mich überrascht:
- form_for :account, :url => account_path do |account|
= account.text_field :name
- account.fields_for :owner do |owner|
= owner.text_field :name
Und das ist der Controller-Code für die neue Aktion:
class AccountsController < ApplicationController
# GET /account/new
def new
@account = Account.new
end
end
Wenn ich versuche, /account/new zu laden, erhalte ich die folgende Ausnahme:
NameError in Accounts#new
Showing app/views/accounts/new.html.haml where line #63 raised:
@account[owner] is not allowed as an instance variable name
Wenn ich versuche, die mysteriöse „Build“-Methode zu verwenden, wird sie einfach im Controller ausgeblendet, vielleicht weil Build nur für Beziehungen mit mehreren Datensätzen gedacht ist:
class AccountsController < ApplicationController
# GET /account/new
def new
@account = Account.new
@account.owner.build
end
end
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.build
Wenn ich versuche, dies mit @account.owner_attributes = {} im Controller oder @account.owner = User.new einzurichten, erhalte ich wieder den ursprünglichen Fehler: „@account[owner] ist als Instanz nicht zulässig.“ Variablennamen".
Verfügt noch jemand über die neue Methode „accepts_nested_attributes_for“, die mit einer „gehört_to“-Beziehung funktioniert?Gibt es etwas Besonderes oder Anderes, das Sie tun müssen?Alle offiziellen Beispiele und Beispielcodes (wie z. B Tolle Sachen bei Ryans Scraps) befasst sich mit Multi-Record-Assoziationen.
Lösung
ich denke dein accepts_nested_attributes
steht auf der falschen Seite der Beziehung.Vielleicht würde so etwas funktionieren?
class Account < ActiveRecord::Base
belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
has_many :users
end
class User < ActiveRecord::Base
belongs_to :account
has_one :account, :foreign_key => :owner_id
accepts_nested_attributes_for :account
end
Zum Erstellen des Kontos möchten Sie build_account verwenden.
Weitere Beispiele finden Sie in die Dokumente.
Andere Tipps
Ich bin ein paar Monate zu spät dran, aber ich habe versucht, diesen Fehler zu beheben, und meine Situation war, dass ich die Beziehung nicht ändern konnte, um „in die andere Richtung zu schauen“.
Die Antwort ist eigentlich ganz einfach, Sie müssen dies in Ihrer neuen Aktion tun:
@account.build_owner
Der Grund, warum das Formular mit „fields_for“ nicht angezeigt wurde, war, dass es kein gültiges Objekt hatte.Da hattest du die richtige Idee mit:
@account.owner.build
Dies ist jedoch nicht der richtige Weg belongs_to
arbeiten.Diese Methode wird nur mit generiert has_many
Und has_and_belongs_to_many
.
Referenz:http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
Ich verwende Rails 2.3.5 und habe dasselbe bemerkt.Wenn man sich die Quelle für „nested_attributes.rb“ von active_record ansieht, sieht es so aus, als ob „gehört_to“ gut funktionieren sollte.Es scheint also, dass es sich um einen Fehler bei „verschachtelten Formularen“ handelt.
Ich habe ein verschachteltes Formular genau wie Ihres, mit User belongs_to :address
, Und Address
ist unabhängig vom Benutzer.
Dann mache ich es einfach im Formular <% f.fields_for :address_attributes do |address_form| %>
anstatt <% f.fields_for :address do |address_form| %>
.Vorübergehender Hack, bis es einen besseren Weg gibt, aber das funktioniert.Die Methode accepts_nested_attributes_for
erwartet, dass die Parameter etwas enthalten wie:
{user=>{address_attributes=>{attr1=>'one',attr2=>'two'}, name=>'myname'}
...Aber fields_for
produziert:
{user=>{address=>{attr1=>'one',attr2=>'two'}, name=>'myname'}
Auf diese Weise müssen Sie das nicht hinzufügen has_one :account
zu Ihrem Code, was in meinem Fall nicht funktioniert.
Aktualisieren:Eine bessere Antwort gefunden:
Hier ist der Kern des Codes, den ich verwende, damit dies richtig funktioniert:
Schienen verschachtelter Formulare mit „gehört_to“ Gist
Hoffentlich hilft das.
class Account < ActiveRecord::Base
belongs_to :owner :class_name => 'User', :foreign_key => 'owner_id'
end
Für mich geht das.:foreign_key => 'owner_id' war in meinem Fall das Hauptproblem.