J'ai un Bill
objet, qui a de nombreux Due
objets. L' Due
objet appartient également à un Person
. Je veux un formulaire qui puisse créer le Bill
et ses enfants Dues
sur une seule page. J'essaie de créer un formulaire en utilisant des attributs imbriqués, similaires à ceux de ce Railscast .
Le code pertinent est répertorié ci-dessous:
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
factures_controller.rb
# GET /bills/new
def new
@bill = Bill.new
3.times { @bill.dues.build }
end
factures / _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 %>
factures / _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>
MISE À JOUR vers factures_controller.rb Cela fonctionne!
def bill_params
params
.require(:bill)
.permit(:company, :month, :year, dues_attributes: [:amount, :person_id])
end
Les champs appropriés sont rendus sur la page (mais sans liste déroulante pour le Person
moment) et la soumission est réussie. Cependant, aucune des cotisations enfants n'est enregistrée dans la base de données et une erreur est renvoyée dans le journal du serveur:
Unpermitted parameters: dues_attributes
Juste avant l'erreur, le journal affiche ceci:
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"}
Y a-t-il eu des changements dans Rails 4?
la source
Réponses:
Il semble qu'il y ait un changement dans la gestion de la protection des attributs et que vous devez maintenant ajouter les paramètres à la liste blanche dans le contrôleur (au lieu de attr_accessible dans le modèle) car l'ancien gem optionnel strong_parameters est devenu une partie du noyau Rails.
Cela devrait ressembler à ceci:
Donc
params.require(:model).permit(:fields)
serait utiliséet pour les attributs imbriqués quelque chose comme
Vous trouverez plus de détails dans la documentation de l'API Ruby edge et dans strong_parameters sur github ou ici
la source
def bill_params params.require(:bill).permit(:company, :month, :year, :dues_attributes[:amount, :person_id]) end
maintenant cette erreur: pas de conversion implicite de Symbol en Integerpets_attributes: [:id, :name, :category]
Sinon, lorsque vous modifiez, chaque animal sera de nouveau créé.Person.create(person_params)
ou il n'appellera pas la méthode. Au lieu de cela, vous obtiendrezActiveModel::ForbiddenAttributesError
.:_destroy
paramètre masqué à la liste blanche . iepets_attributes: [:id, :name, :category, :_destroy]
À partir des documents
Les attributs imbriqués se présentent sous la forme d'un hachage. Dans mon application, j'ai un modèle Question.rb qui accepte les attributs imbriqués pour un modèle Answer.rb (où l'utilisateur crée des choix de réponse pour une question qu'il crée). Dans le questions_controller, je fais ceci
Tout dans le hachage de question est autorisé, y compris les attributs de réponse imbriqués. Cela fonctionne également si les attributs imbriqués se présentent sous la forme d'un tableau.
Cela dit, je me demande s'il y a un problème de sécurité avec cette approche, car elle autorise fondamentalement tout ce qui se trouve à l'intérieur du hachage sans spécifier exactement ce que c'est, ce qui semble contraire à l'objectif des paramètres forts.
la source
.permit!
la seule option? Je ne peux pas le faire fonctionner même avec tous les attributs du modèle autorisés car il s'étouffe sur le tableau.ou vous pouvez simplement utiliser
la source
En fait, il existe un moyen de simplement lister tous les paramètres imbriqués.
Cette méthode a un avantage par rapport aux autres solutions. Il permet d'autoriser des paramètres profondément imbriqués.
Alors que d'autres solutions comme:
Ne fais pas ça.
La source:
https://github.com/rails/rails/issues/9454#issuecomment-14167664
la source
Aujourd'hui je suis tombé sur ce même problème, alors que je travaillais sur rails 4, j'ai pu le faire fonctionner en structurant mes champs comme:
Ensuite, dans mon contrôleur, j'ai mes paramètres forts comme:
Tout fonctionne!
la source
Si vous utilisez un champ JSONB, vous devez le convertir en JSON avec .to_json (ROR)
la source