web-dev-qa-db-fra.com

Comment utiliser Rails 4 paramètres forts avec has_many: par association?

J'ai du mal à obtenir un has_many: grâce à une association travaillant avec Rails 4 paramètres forts. J'ai un modèle appelé Checkout et je dois sélectionner une personne dans le Employee modèle dans le nouveau formulaire de paiement. Les caisses et les employés sont associés via un modèle Employment.

J'obtiens cette erreur lorsque j'essaye de créer une nouvelle caisse:

NoMethodError in CheckoutsController#create
undefined method `employee' for #<Checkout:0x007ff4f8d07f88>

Il semble qu'il y ait un problème avec mon action de création, mes paramètres de paiement ou mon nouveau formulaire de paiement. Voici l'action de création:

  def create    
    @user = current_user
    @checkout = @user.checkouts.build(checkout_params)

    respond_to do |format|
      if @checkout.save
        format.html { redirect_to @checkout, notice: 'Checkout was successfully created.' }
      else
        format.html { render action: 'new' }
      end
    end
  end

Mes paramètres de paiement:

def checkout_params
      params.require(:checkout).permit(:job, :employee_ids, :shift, :date, :hours, :sales, :tips, :owed, :collected, :notes)
end

Mon nouveau formulaire de paiement:

<div class="field">
     <%= f.label :employee %><br>
     <%= f.collection_select(:employee_ids, Employee.all.collect, :id, :full_name, {:Prompt => "Please select"} ) %>
</div>

Mais je ne peux pas comprendre ce qui a changé avec Rails 4 et des paramètres forts. Dans Rails 3 ce type d'association et de formulaire a fonctionné pour moi en utilisant attr_accessible à la place) de paramètres_ forts.

Fichiers pertinents

Trace complète de l'erreur: https://Gist.github.com/leemcalilly/0cb9e2b539f9e1925a3d

models/checkout.rb: https://Gist.github.com/leemcalilly/012d6eae6b207beb147a

controllers/checkouts_controller.rb: https://Gist.github.com/leemcalilly/a47466504b7783b3177

views/checkouts/_form.html.erb https://Gist.github.com/leemcalilly/ce0b4049b23e3d431f55

models/employee.rb: https://Gist.github.com/leemcalilly/46150bee3e6216fa29d1

controllers/employees_controller.rb: https://Gist.github.com/leemcalilly/04f3acdac0c9a678bca8

models/Employment.rb: https://Gist.github.com/leemcalilly/6adad966dd48cb9d1b39

db/schema.rb: https://Gist.github.com/leemcalilly/36be318c677bad75b211

34
Lee McAlilly

Gardez à l'esprit que le nom que vous donnez à vos paramètres forts (employés, ID_employé, etc.) est largement hors de propos car il dépend du nom vous choisissez de soumettre. Les paramètres forts ne fonctionnent pas comme par magie selon les conventions de dénomination.

La raison https://Gist.github.com/leemcalilly/a71981da605187d46d96 génère une erreur "Paramètre non autorisé" sur 'employee_ids' parce qu'il attend un tableau de valeurs scalaires, par https://github.com/Rails/strong_parameters#nested-parameters , pas seulement une valeur scalaire.

# If instead of:
... "employee_ids" => "1" ...
# You had:
... "employee_ids" => ["1"]

Ensuite, vos paramètres forts fonctionneraient, en particulier:

... { :employee_ids => [] } ...

Parce qu'il reçoit un tableau de valeurs scalaires au lieu d'une simple valeur scalaire.

53
Denzel

Ok, donc je n'avais pas besoin d'imbriquer les paramètres. C'est ce qui a fini par travailler pour moi:

# Never trust parameters from the scary internet, only allow the white list through.
def checkout_params
  params.require(:checkout).permit(:job, :shift, :employee_ids, :date, :hours, :sales, :tips, :owed, :collected, :notes)
end

Voici la combinaison des changements qui ont fonctionné.

Je ne comprends toujours pas pourquoi cela a fonctionné.

4
Lee McAlilly

Je peux publier la déclaration de permis que j'utilise dans l'un de mes contrôleurs. Cela a aussi une association plusieurs à plusieurs. Vous imbriquez le tableau des autorisations. Utilisez l'association de recherche dans votre relevé de permis. La seule différence devrait être que le vôtre ne sera pas imbriqué une troisième fois.

Dans mon cas, l'association Quote has_many :quote_items.

QuoteItems has_many :quote_options, :through => quote_item_quote_options.

Dans quotes_controller.rb

params.require(:quote).permit(:quote_date, :good_through, :quote_number, quote_items_attributes: [:id,:quote_id, :item_name, :material_id, quote_item_quote_options_attributes:[:quote_option_id,:quote_item_id,:qty,:_destroy,:id]])
0
ctilley79