strong rails multiple array ruby-on-rails arrays strong-parameters

ruby-on-rails - rails - strong parameters nested attributes



Cómo permitir una matriz con parámetros fuertes. (5)

Debería ser como

params.permit(:id => [])

También desde la versión 4+ de rieles puedes usar:

params.permit(id: [])

Tengo una aplicación de Rails 3 que funciona y usa has_many: a través de asociaciones que no lo es, ya que la rehago como una aplicación de Rails 4, lo que me permite guardar los identificadores del modelo asociado en la versión de Rails 4.

Estos son los tres modelos relevantes que son los mismos para las dos versiones.

Categorización.rb

class Categorization < ActiveRecord::Base belongs_to :question belongs_to :category end

Question.rb

has_many :categorizations has_many :categories, through: :categorizations

Category.rb

has_many :categorizations has_many :questions, through: :categorizations

En ambas aplicaciones, los identificadores de categoría se pasan a la acción crear como esta

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

En la aplicación Rails 3, cuando creo una nueva pregunta, se inserta en la tabla de preguntas y luego en la tabla de categorizaciones.

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]]

En la aplicación rails 4, después de procesar los parámetros en QuestionController # create, aparece este error en los registros del servidor.

Unpermitted parameters: category_ids

y la pregunta solo se está insertando en la tabla de preguntas

(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

Aunque no estoy almacenando las category_ids en el modelo de Preguntas, configuro category_ids como un parámetro permitido en el questions_controller

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

¿Alguien puede explicar cómo se supone que debo guardar las category_ids? Tenga en cuenta que no hay ninguna acción de creación en el categories_controller.rb de ninguna de las aplicaciones.

Estas son las tres tablas que son iguales en ambas aplicaciones.

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

Actualizar

Esta es la acción de crear desde la aplicación Rails 3.

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

Esta es la acción de crear desde la aplicación Rails 4.

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

Este es el método 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


Este https://github.com/rails/strong_parameters parece la sección relevante de los documentos:

Los tipos de escalar permitidos son: String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch :: Http :: UploadedFile y Rack :: Test :: UploadedFile.

Para declarar que el valor en params debe ser una matriz de valores escalares permitidos, asigne la clave a una matriz vacía:

params.permit(:id => [])

En mi aplicación, los category_ids se pasan a la acción de crear en una matriz

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

Por lo tanto, cuando declaro parámetros fuertes, explícitamente establezco category_ids como una matriz

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

¡Funciona perfectamente ahora!


No puedo comentar todavía, pero siguiendo la solución de Fellow Stranger, también puede seguir anidando en caso de que tenga claves cuyos valores son una matriz. Me gusta esto:

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

Esto funciona:

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


Si desea permitir una matriz de hashes (o an array of objects desde la perspectiva de JSON)

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

2 puntos a notar aquí:

  1. array debe ser el último argumento del método de permit .
  2. debe especificar las claves del hash en la matriz, de lo contrario obtendrá un error Unpermitted parameter: array , que es muy difícil de depurar en este caso.

Si tienes una estructura hash como esta:

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

Entonces así es como lo hice funcionar:

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