299 votes

comment permettre à un tableau avec des paramètres de poids

J'ai un fonctionnement Rails 3 app qui utilise has_many :par le biais d'associations qui n'est pas, comme je le refaire car un les Rails 4 app, ce qui me permet d'enregistrer les id à partir du modèle associé dans les Rails 4 version.

Ce sont les trois modèles sont les mêmes pour les deux versions.

La catégorisation.rb

class Categorization < ActiveRecord::Base

  belongs_to :question
  belongs_to :category
end

Question.rb

has_many :categorizations
has_many :categories, through: :categorizations

De la catégorie.rb

has_many :categorizations
has_many :questions, through: :categorizations

Dans les deux applications, l'id de catégorie sont passé dans l'action de création comme ceci

  "question"=>{"question_content"=>"How do you spell car?", "question_details"=>"blah ", "category_ids"=>["", "2"],

Dans les Rails 3 app, lorsque je crée une nouvelle question, il s'insère dans les questions de la table, puis dans les catégorisations de la table

 SQL (82.1ms)  INSERT INTO "questions" ("accepted_answer_id", "city", "created_at", "details", "province", "province_id", "question", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)  [["accepted_answer_id", nil], ["city", "dd"], ["created_at", Tue, 14 May 2013 17:10:25 UTC +00:00], ["details", "greyound?"], ["province", nil], ["province_id", 2], ["question", "Whos' the biggest dog in the world"], ["updated_at", Tue, 14 May 2013 17:10:25 UTC +00:00], ["user_id", 53]]
  SQL (0.4ms)  INSERT INTO "categorizations" ("category_id", "created_at", "question_id", "updated_at") VALUES (?, ?, ?, ?)  [["category_id", 2], ["created_at", Tue, 14 May 2013 17:10:25 UTC +00:00], ["question_id", 66], ["updated_at", Tue, 14 May 2013 17:10:25 UTC +00:00]]

Dans les rails 4 app, après qu'il traite les paramètres de QuestionController#créer, j'obtiens cette erreur dans les logs du serveur

Unpermitted parameters: category_ids

et la question est seulement de s'insérer dans les questions de la table

 (0.2ms)  BEGIN
  SQL (67.6ms)  INSERT INTO "questions" ("city", "created_at", "province_id", "question_content", "question_details", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["city", "dd"], ["created_at", Tue, 14 May 2013 17:17:53 UTC +00:00], ["province_id", 3], ["question_content", "How's your car?"], ["question_details", "is it runnign"], ["updated_at", Tue, 14 May 2013 17:17:53 UTC +00:00], ["user_id", 12]]
   (31.9ms)  COMMIT

Bien que je ne suis pas le stockage de la category_ids sur le modèle des Questions, j'ai mis category_ids comme un permis de paramètre dans le questions_controller

   def question_params

      params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids)
    end

Quelqu'un peut-il expliquer comment je suis censé enregistrer le category_ids? Notez qu'il n'est pas de créer une action dans le categories_controller.rb soit de l'application.

Ce sont les trois tableaux qui sont les mêmes dans les deux applications

 create_table "questions", force: true do |t|
    t.text     "question_details"
    t.string   "question_content"
    t.integer  "user_id"
    t.integer  "accepted_answer_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "province_id"
    t.string   "city"
  end

 create_table "categories", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "categorizations", force: true do |t|
    t.integer  "category_id"
    t.integer  "question_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

Mise à jour

C'est l'action de créer des Rails 3 app

  def create
      @question = Question.new(params[:question])
      respond_to do |format|
      if @question.save
        format.html { redirect_to @question, notice: 'Question was successfully created.' }
        format.json { render json: @question, status: :created, location: @question }
      else
        format.html { render action: "new" }
        format.json { render json: @question.errors, status: :unprocessable_entity }
      end
    end
end

C'est l'action de créer les Rails 4 app

   def create
      @question = Question.new(question_params)

       respond_to do |format|
      if @question.save
        format.html { redirect_to @question, notice: 'Question was successfully created.' }
        format.json { render json: @question, status: :created, location: @question }
      else
        format.html { render action: "new" }
        format.json { render json: @question.errors, status: :unprocessable_entity }
      end
    end
    end

C'est la méthode question_params

 private
    def question_params 
      params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids)
    end

0 votes

W

0 votes

@

597voto

Leahcim Points 5965

Cette https://github.com/rails/strong_parameters me semble que la section pertinente de la documentation:

Le permis des types scalaires sont de la Chaîne, Symbole, NilClass, Numérique, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile et Rack::Test::UploadedFile.

De déclarer que la valeur de paramètres doit être un tableau de valeurs scalaires carte la clé d'un tableau vide:

params.permit(:id => [])

Dans mon application, category_ids sont passés à l'action de création d'un tableau

"category_ids"=>["", "2"],

Par conséquent, lors de la déclaration des paramètres de poids, j'ai défini explicitement category_ids être un tableau

params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids => [])

Fonctionne parfaitement maintenant!

111 votes

J'ai également remarqué que les déclarations pour les tableaux devraient se trouver à la fin de la liste des attributs. Sinon, j'obtiens une erreur de syntaxe syntax error, unexpected ')', expecting =>

51 votes

La raison pour laquelle les déclarations de tableaux (paramètres imbriqués) sont à la fin est que ActionController::Parameters.permit s'attend à ce que chaque argument soit un Hash ou un Symbol. La magie de Ruby va transformer toutes les paires clé-valeur s en fin d'un appel de méthode en un seul hachage, mais Ruby ne saura pas quoi faire si vous mélangez des symboles avec des paires clé/valeur dans votre appel de méthode.

0 votes

Comment puis-je faire cela en tant que séparer param pour category_ids

112voto

Brian Points 3134

Si vous souhaitez autoriser un tableau de hachages (ou an array of objects du point de vue de JSON)

params.permit(:foo, array: [:key1, :key2])

2 points à noter ici :

  1. array doit être le dernier argument de la fonction permit méthode.
  2. vous devez spécifier les clés du hachage dans le tableau, sinon vous obtiendrez une erreur Unpermitted parameter: array ce qui est très difficile à déboguer dans ce cas.

27voto

Matias Seguel Points 480

Ce devrait être comme

params.permit(:id => [])

De plus, depuis la version 4+ de rails, vous pouvez utiliser :

params.permit(id: [])

20voto

Fellow Stranger Points 1068

Si vous avez une structure de hachage comme celle-ci :

Parameters: {"link"=>{"title"=>"Something", "time_span"=>[{"start"=>"2017-05-06T16:00:00.000Z", "end"=>"2017-05-06T17:00:00.000Z"}]}}

Voici comment je l'ai fait fonctionner :

params.require(:link).permit(:title, time_span: [[:start, :end]])

9voto

Daniel Duque Points 133

Je ne peux pas encore faire de commentaires, mais en suivant la solution de Fellow Stranger, vous pouvez également conserver l'imbrication dans le cas où vous avez des clés dont les valeurs sont un tableau. Comme ceci :

filters: [{ name: 'test name', values: ['test value 1', 'test value 2'] }]

Cela fonctionne :

params.require(:model).permit(filters: [[:name, values: []]])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X