Rails 4 中从控制器方法创建表单更新按钮的问题

Issues with Createing a form update button from a controller method in Rails 4

嘿,我正在 Rails 4 Ruby 2 中构建 CAD 应用程序。

Background:

我有一个 f.time_select 的表单域,我想用一个在现场显示的按钮替换它。按下时,我希望它更新我的调用 table 中的 unit_on_scene 列,然后将我重定向到 show.html.erb 页面。

我的按钮看起来像:

<%= link_to "On Scene", update_unit_on_scene_call_path class: 'btn btn-success btn-sm' %>

我的 routes.rb 看起来像:

  resources :calls do 
    collection do
      get 'history'
    end
    member do
      patch :update_unit_on_scene
    end
  end

然后在 Rake Routes 中给了我这个 link:

update_unit_on_scene_call PATCH  /calls/:id/update_unit_on_scene(.:format) calls#update_unit_on_scene

我的控制器方法如下所示:

def update_unit_on_scene
  @call = Call.find(params[:id])
  @call.unit_on_scene = DateTime.now
  @call.save

  respond_to do |format|
    if @call.update(call_params)
      format.html { redirect_to @call, notice: "On Scene Time Successfully Updated. - You Are Now Logged Out Of Service" }
    else
      format.html { render action: 'edit' }
    end
  end
end

我现在遇到的问题是,当我按下按钮时,出现以下错误:

No route matches [GET] "/calls/3/update_unit_on_scene"

好像在寻找另一页??

任何帮助将不胜感激,因为我以前从未在这条路上冒险过。

谢谢。

编辑 # 1:

Associated Warning when Button Clicked:

ActionController::ParameterMissing in CallsController#update_unit_on_scene
param is missing or the value is empty: call

Extracted source (around line #107):
105
106
107
108
109
110

    # Never trust parameters from the scary internet, only allow the white list through.
    def call_params
      params.require(:call).permit(:call_time, :status, :primary_type, :secondary_type, :site, :address, :unit_1, :unit_2, :unit_3, :unit_4, :call_details, :unit_on_scene, :unit_clear, :call_num, :site_id, :user_id, :unit2_os, :unit2_cl, :unit3_os, :unit3_cl, :unit4_os, :unit4_cl)
    end
end

Server Log:

Started PATCH "/calls/3/update_unit_on_scene" for ::1 at 2015-11-22 01:38:49 -0700
      ActiveRecord::SchemaMigration Load (0.2ms)  SELECT "schema_migrations".* FROM "schema_migrations"
    Processing by CallsController#update_unit_on_scene as HTML
      Parameters: {"authenticity_token"=>"hH4juJAS7bxs+HHPjSuEDLpucwAh2i2QODH8DvF3JQVxhzhet1AcAs6xzib6AezrlLJ3yZrHLea5ey8206gIqA==", "id"=>"3"}
      Call Load (0.4ms)  SELECT  "calls".* FROM "calls" WHERE "calls"."id" =  LIMIT 1  [["id", 3]]
       (0.1ms)  BEGIN
      SQL (0.6ms)  UPDATE "calls" SET "unit_on_scene" = , "updated_at" =  WHERE "calls"."id" =   [["unit_on_scene", "2015-11-22 08:38:50.027783"], ["updated_at", "2015-11-22 08:38:50.031354"], ["id", 3]]
       (6.4ms)  COMMIT
    Completed 400 Bad Request in 48ms (ActiveRecord: 9.9ms)

    ActionController::ParameterMissing (param is missing or the value is empty: call):
      app/controllers/calls_controller.rb:107:in `call_params'
      app/controllers/calls_controller.rb:89:in `block in update_unit_on_scene'
      app/controllers/calls_controller.rb:88:in `update_unit_on_scene'


      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_source.erb (9.0ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.2ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.5ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (53.4ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.6ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.6ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.7ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.9ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (42.8ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.8ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.6ms)
      Rendered /Users/TaurenLTD1/.rvm/gems/ruby-2.2.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (96.0ms)

除非指定方法,否则 link_to 助手将发出 GET 请求。

因此,您需要在 link_to:

中指定方法 (method: :patch)
<%= link_to "On Scene", update_unit_on_scene_call_path(@call), class: 'btn btn-success btn-sm', method: :patch %>

此外,将您的控制器操作更改为:

  def update_unit_on_scene
    @call = Call.find(params[:id])
    @call.unit_on_scene = DateTime.now

    respond_to do |format|
      if @call.save
        format.html { redirect_to @call, notice: "On Scene Time Successfully Updated. - You Are Now Logged Out Of Service" }
      else
        format.html { render action: 'edit' }
      end
    end
  end