使用button_to进行更新操作时不满意的强大参数

时间:2015-05-23 07:44:09

标签: ruby-on-rails-4 strong-parameters

在使用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:在   '阻止更新'

3 个答案:

答案 0 :(得分:3)

我能够根据this thread中的信息最终解决此问题。

我没有将参数放在自己的哈希中作为sample_object的另一个参数,而是将它们包含在button_to方法的调用中。第一个参数需要是模型的ID,第二个参数需要是模型的名称作为键,其中所需属性的哈希值作为其值。 (以下示例):

plan_path

答案 1 :(得分:0)

根据http://apidock.com/rails/ActionView/Helpers/UrlHelper/button_toparams应该是一个单独的哈希

= 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的一部分,因为您尝试使用表单字段对我来说感觉更正确。)

或者,如果此更新操作未被任何其他表单使用,则更改它以匹配提交的数据。我通常不这样做 - 这很容易,但如果事情以可预测的方式表现,你的应用会更容易思考。