在使用button_to
执行update
操作时,我无法理解如何满足强params。我正在尝试将名为active
的属性设置为true
的值,以用于名为Plan
的类的现有实例。
(请注意,我在这里使用HAML作为我的观点。)
这有效:
= form_for(plan, remote: true) do |f|
= f.hidden_field :active, value: true
= f.submit 'set active'
但这不是:
= button_to "set active", plan_path(plan, active: true), method: :put, remote: true
错误
7ms内完成了400次错误请求(ActiveRecord:1.1ms)
ActionController :: ParameterMissing - 缺少param或值为 空的:计划:
actionpack(4.2.1)lib / action_controller / metal / strong_parameters.rb:249:在'require'中 ()用户/ Rob / Sites / drexel_msis_planner / app / controllers / plans_controller.rb:77:在'plan_params'中
()用户/ Rob / Sites / drexel_msis_planner / app / controllers / plans_controller.rb:45:'更新中的块'
actionpack(4.2.1)lib / action_controller / metal / mime_responds.rb:210:在'respond_to'中 ()用户/ Rob / Sites / drexel_msis_planner / app / controllers / plans_controller.rb:44:在'update'中
路线
user_plans GET /users/:user_id/plans(.:format) plans#index
POST /users/:user_id/plans(.:format) plans#create
new_user_plan GET /users/:user_id/plans/new(.:format) plans#new
edit_plan GET /plans/:id/edit(.:format) plans#edit
plan PATCH /plans/:id(.:format) plans#update
PUT /plans/:id(.:format) plans#update
DELETE /plans/:id(.:format) plans#destroy
控制器
# PATCH/PUT /plans/1
def update
respond_to do |format|
if @plan.update(plan_params)
format.js { flash.now[:notice] = "Plan was successfully updated." }
end
end
end
private
def plan_params
params.require(:plan).permit(:user_id, :name, :active)
end
这似乎是一个如此愚蠢的问题,但我无法弄清楚,the API documentation似乎没有提供任何线索,说明为什么它不起作用。
这些只是我尝试过的一些变体(后面跟着它附带的错误信息):
= button_to "set active", plan_path(plan: plan, active: true), method: :put, remote: true
ActionController :: UrlGenerationError - 没有路由匹配 {:action =>“update”,:active => true,:controller =>“plans”,:plan =>#, :user_id =>“104”}缺少必需的键:[:id]:
= button_to "set active", plan_path(id: plan.id, active: true), method: :put, remote: true
在17ms内完成了400个错误请求(ActiveRecord:2.1ms)
ActionController :: ParameterMissing - 缺少param或值为 空:计划:actionpack(4.2.1) lib / action_controller / metal / strong_parameters.rb:249:在`require'
= button_to "set active", plan, active: true, method: :put, remote: true
ActionController :: ParameterMissing - 缺少param或值为 空:计划:actionpack(4.2.1) lib / action_controller / metal / strong_parameters.rb:249:在'require'中 () 用户/罗布/站点/ drexel_msis_planner /应用/控制器/ plans_controller.rb:77:在 'plan_params'() 用户/罗布/站点/ drexel_msis_planner /应用/控制器/ plans_controller.rb:45:在 '阻止更新'
答案 0 :(得分:3)
我能够根据this thread中的信息最终解决此问题。
我没有将参数放在自己的哈希中作为sample_object
的另一个参数,而是将它们包含在button_to
方法的调用中。第一个参数需要是模型的ID,第二个参数需要是模型的名称作为键,其中所需属性的哈希值作为其值。 (以下示例):
plan_path
答案 1 :(得分:0)
根据http://apidock.com/rails/ActionView/Helpers/UrlHelper/button_to,params
应该是一个单独的哈希
= button_to "set active", plan, method: :put, remote: true, params: { :active => true }
答案 2 :(得分:0)
如果您查看提交的参数,不同之处在于您的表单会导致params
{ "id" => 123, "plan" => {"active" => true}, "controller" => "...", "action" => "..."}
而第二个结果是
{ "id" => 123, "active" => true, "controller" => "...", "action" => "..."}
在这种情况下,params[:plan]
为零,这会导致您看到的错误。
有多种方法可以解决这个问题。您可以更改提交的参数以匹配控制器当前所需的参数,例如
button_to set_active, plan, method: :put, remote: true, params: {"plan[active]" => 1}
(您也可以将参数作为表单URL的一部分,因为您尝试使用表单字段对我来说感觉更正确。)
或者,如果此更新操作未被任何其他表单使用,则更改它以匹配提交的数据。我通常不这样做 - 这很容易,但如果事情以可预测的方式表现,你的应用会更容易思考。