cómo permitir una matriz con parámetros fuertes
Tengo una aplicación Rails 3 en funcionamiento que usa has_many :a través de asociaciones que no lo es, ya que la rehizo como una aplicación Rails 4, lo que me permite guardar ID del modelo asociado en la versión Rails 4.
Estos son los tres modelos relevantes son los mismos para las dos versiones.
Categorización.rb
class Categorization < ActiveRecord::Base
belongs_to :question
belongs_to :category
end
Pregunta.rb
has_many :categorizations
has_many :categories, through: :categorizations
Categoría.rb
has_many :categorizations
has_many :questions, through: :categorizations
En ambas aplicaciones, los id de categoría se pasan a la acción create como esto
"question"=>{"question_content"=>"How do you spell car?", "question_details"=>"blah ", "category_ids"=>["", "2"],
En la aplicación Rails 3, cuando creo una pregunta nueva, 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, recibo este error en los registros del servidor
Unpermitted parameters: category_ids
Y la pregunta solo se inserta 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 soy almacenar el id de categoría en las Preguntas modelo, me puse como un id de categoría parámetro permitido en questions_controller
def question_params
params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids)
end
¿Puede alguien explicar cómo se supone que debo guardar los category_ids? Nota, no hay ninguna acción create en categories_controller.rb de cualquiera 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 create 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 create 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 question_params método
private
def question_params
params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids)
end
5 answers
Esto https://github.com/rails/strong_parameters parece que la sección relevante de los documentos:
Los tipos escalares permitidos son String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile and Rack::Test:: UploadedFile.
Para declarar que el valor en parámetros debe ser una matriz de valores escalares permitidos mapear la clave a una matriz vacía:
params.permit(:id => [])
En mi aplicación, el category_id se pasan a la acción de crear en una matriz
"category_ids"=>["", "2"],
Por lo tanto, cuando declaro parámetros fuertes, establezco explícitamente category_ids como un array
params.require(:question).permit(:question_details, :question_content, :user_id, :accepted_answer_id, :province_id, :city, :category_ids => [])
Funciona perfectamente ahora!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-26 16:05:43
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 tener en cuenta aquí:
-
array
debe ser el último argumento del métodopermit
. - 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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-17 09:53:42
Debería ser como
params.permit(:id => [])
También desde rails versión 4 + puedes usar:
params.permit(id: [])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-18 16:05:21
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 conseguí que funcionara:
params.require(:link).permit(:title, time_span: [[:start, :end]])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-03 15:49:28
Todavía no puedo comentar, pero siguiendo la solución de Compañeros extraños también puede seguir anidando en caso de que tenga claves cuyos valores son una matriz. Así:
filters: [{ name: 'test name', values: ['test value 1', 'test value 2'] }]
Esto funciona:
params.require(:model).permit(filters: [[:name, values: []]])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-12 16:19:33