我的rails应用程序中有一个accepts_nested_attributes_for
表单,我就是无法让它工作。当我试图编辑父对象时,我一直得到Unpermitted parameter
,尽管我认为我已经允许了这个参数。
class Response < ApplicationRecord
has_many :response_threads, :dependent => :destroy
accepts_nested_attributes_for :response_threads
end
class ResponseThread < ApplicationRecord
belongs_to :response
has_many :response_thread_updates, :dependent => :destroy
accepts_nested_attributes_for :response_thread_updates
end
class ResponseThreadUpdate < ApplicationRecord
belongs_to :response_thread
end
在responses_controller
:中
def response_params
params.require(:response).permit(:name, :response_thread, response_thread_attributes: [:id, :name] )
end
/responses/1/edit
:的表格
<%= form_with(model: response) do |f| %>
<%= f.fields_for :response_thread do |ff| %>
<%= ff.label :name %>
<%= ff.text_field :name %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
这是我的模式(更新和创建的日期时间删除(:
create_table "responses", force: :cascade do |t|
t.string "name"
end
create_table "response_threads", force: :cascade do |t|
t.integer "response_id"
t.string "name"
end
create_table "response_thread_updates", force: :cascade do |t|
t.integer "response_thread_id"
t.string "name"
end
错误:
Started PATCH "/responses/1" for ::1 at 2021-06-28 20:56:24 -0400
Processing by ResponsesController#update as HTML
Parameters: {"authenticity_token"=>"[FILTERED]", "response"=>{"response_thread"=>{"name"=>"asd"}}, "commit"=>"Update Response", "id"=>"1"}
Response Load (0.2ms) SELECT "responses".* FROM "responses" WHERE "responses"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/responses_controller.rb:63:in `set_response'
Unpermitted parameter: :response_thread
我的routes.rb
:
Rails.application.routes.draw do
resources :responses do
resources :response_threads do
resources :response_thread_updates do
end
end
end
root to: "responses#new"
end
我正在编辑的response
上有一个现有的response_thread
。我甚至还没有尝试更新response_thread_update,因为我只赶上了第一级。应用程序没有其他更改,因为我创建了一个新的应用程序来解决这个问题。我只是在努力学习Rails,所以请告诉我我做错了什么!
首先,让我们检查StrongParameters如何允许属性:
StrongParameters
包装您的输入参数(Hash
(- 如果permit属性是标量(String或Symbol(,那么只有当您的输入params有任何等于该属性的键时,它才允许
- 如果permit属性是Hash,那么它将遍历属性的键并检查每个标量(如上所述(,如果是空散列,它将允许任何内容
在您的情况下,您设置了一个permit属性response_thread
作为标量,但您的输入参数包含一个Hashresponse_thread
,因此StrongParameters
找不到,它将返回Unpermitted parameter
错误。
params = ActionController::Parameters.new({"response"=>{"response_thread"=>{"name"=>"asd"}}, "commit"=>"Update Response", "id"=>"1"}
# scalar
params.require(:response).permit(:response_thread) # Unpermitted parameter: :response_thread
# hash
params.require(:response).permit(response_thread: :name) # ok
params.require(:response).permit(response_thread: [:name]) # ok
# empty hash
params.require(:response).permit(response_thread: {}) # ok
其次,允许nested attributes
的设置方式不正确,应该是params.require(:response).permit(:name, response_threads_attributes: [:id, :name])
(注意response_threads
不是response_thread
(而且<%= f.fields_for :response_threads do |ff| %>