Ich habe ein Bill
Objekt, das viele Due
Objekte hat. Das Due
Objekt gehört auch zu a Person
. Ich möchte ein Formular, mit dem das Bill
und seine untergeordneten Dues
Elemente auf einer Seite erstellt werden können. Ich versuche, ein Formular mit verschachtelten Attributen zu erstellen, ähnlich denen in diesem Railscast .
Der relevante Code ist unten aufgeführt:
due.rb
class Due < ActiveRecord::Base
belongs_to :person
belongs_to :bill
end
bill.rb
class Bill < ActiveRecord::Base
has_many :dues, :dependent => :destroy
accepts_nested_attributes_for :dues, :allow_destroy => true
end
bill_controller.rb
# GET /bills/new
def new
@bill = Bill.new
3.times { @bill.dues.build }
end
Rechnungen / _form.html.erb
<%= form_for(@bill) do |f| %>
<div class="field">
<%= f.label :company %><br />
<%= f.text_field :company %>
</div>
<div class="field">
<%= f.label :month %><br />
<%= f.text_field :month %>
</div>
<div class="field">
<%= f.label :year %><br />
<%= f.number_field :year %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<%= f.fields_for :dues do |builder| %>
<%= render 'due_fields', :f => builder %>
<% end %>
<% end %>
Rechnungen / _due_fields.html.erb
<div>
<%= f.label :amount, "Amount" %>
<%= f.text_field :amount %>
<br>
<%= f.label :person_id, "Renter" %>
<%= f.text_field :person_id %>
</div>
UPDATE to bill_controller.rb Das funktioniert!
def bill_params
params
.require(:bill)
.permit(:company, :month, :year, dues_attributes: [:amount, :person_id])
end
Die richtigen Felder werden auf der Seite gerendert (allerdings noch ohne Dropdown Person
) und das Senden ist erfolgreich. Es wird jedoch keine der untergeordneten Gebühren in der Datenbank gespeichert, und im Serverprotokoll wird ein Fehler ausgegeben:
Unpermitted parameters: dues_attributes
Kurz vor dem Fehler zeigt das Protokoll Folgendes an:
Started POST "/bills" for 127.0.0.1 at 2013-04-10 00:16:37 -0700
Processing by BillsController#create as HTML<br>
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"ipxBOLOjx68fwvfmsMG3FecV/q/hPqUHsluBCPN2BeU=",
"bill"=>{"company"=>"Comcast", "month"=>"April ",
"year"=>"2013", "dues_attributes"=>{
"0"=>{"amount"=>"30", "person_id"=>"1"},
"1"=>{"amount"=>"30", "person_id"=>"2"},
"2"=>{"amount"=>"30", "person_id"=>"3"}}}, "commit"=>"Create Bill"}
Hat sich Rails 4 geändert?
quelle
Antworten:
Anscheinend hat sich die Behandlung des Attributschutzes geändert, und jetzt müssen Sie die Parameter im Controller auf die Whitelist setzen (anstelle von attr_accessible im Modell), da die früheren optionalen gem strong_parameters Teil des Rails Core wurden.
Das sollte ungefähr so aussehen:
Also
params.require(:model).permit(:fields)
würde verwendet werdenund für verschachtelte Attribute so etwas wie
Weitere Details finden Sie in den Ruby Edge API-Dokumenten und strong_parameters auf github oder hier
quelle
def bill_params params.require(:bill).permit(:company, :month, :year, :dues_attributes[:amount, :person_id]) end
Ich erhalte jetzt den folgenden Fehler: Keine implizite Konvertierung von Symbol in Integerpets_attributes: [:id, :name, :category]
Andernfalls wird beim Bearbeiten jedes Haustier erneut erstellt.Person.create(person_params)
wird die Methode nicht aufgerufen. Stattdessen wirst du bekommenActiveModel::ForbiddenAttributesError
.:_destroy
Parameter auf die Whitelist setzen . dhpets_attributes: [:id, :name, :category, :_destroy]
Aus den Dokumenten
Verschachtelte Attribute haben die Form eines Hashs. In meiner App akzeptiert ein Question.rb-Modell verschachtelte Attribute für ein Answer.rb-Modell (wobei der Benutzer Antwortoptionen für eine von ihm erstellte Frage erstellt). Im Fragencontroller mache ich das
Alles im Fragen-Hash ist zulässig, einschließlich der verschachtelten Antwortattribute. Dies funktioniert auch, wenn die verschachtelten Attribute die Form eines Arrays haben.
Trotzdem frage ich mich, ob dieser Ansatz ein Sicherheitsrisiko darstellt, da er grundsätzlich alles zulässt, was sich im Hash befindet, ohne genau anzugeben, was es ist, was dem Zweck starker Parameter zu widersprechen scheint.
quelle
.permit!
die einzige Option? Ich kann es nicht zum Laufen bringen, selbst wenn alle Attribute des Modells zulässig sind, da es das Array drosselt.oder Sie können einfach verwenden
quelle
Tatsächlich gibt es eine Möglichkeit, alle verschachtelten Parameter auf die weiße Liste zu setzen.
Diese Methode hat gegenüber anderen Lösungen Vorteile. Es erlaubt, tief verschachtelte Parameter zuzulassen.
Während andere Lösungen wie:
Tu es nicht.
Quelle:
https://github.com/rails/rails/issues/9454#issuecomment-14167664
quelle
Heute bin ich auf dasselbe Problem gestoßen, als ich an Schienen 4 gearbeitet habe. Ich konnte es zum Laufen bringen, indem ich meine Felder wie folgt strukturierte:
Dann habe ich in meinem Controller meine starken Parameter wie folgt:
Alles funktioniert!
quelle
Wenn Sie ein JSONB-Feld verwenden, müssen Sie es mit .to_json (ROR) in JSON konvertieren.
quelle