Ajax 升级到 Rails 4.2.9 后不起作用(格式::js)

Ajax does not work(format: :js) after upgrading to Rails 4.2.9

代码

我刚刚将 Rails 从 4.1.11 升级到 4.2.9,除 ajax!

外一切正常

我得到了一个 link 与 ajax 的作品,如下所示:

<%= link_to("hide", admin_course_path(id: course.id, hide: "true"), remote: true, format: :js, method: :put) %>

后端看起来像这样:

class Admin::CoursesController < .....
  respond_to :html, :json, :js

  def update
    @course = Course.find(params[:id])

    if params[:hide]
      @course.update_attributes(hide: true)
    else
      .....
    end

    respond_with([:admin, @course])
  end
end

问题

它应该是一个 js ajax,但现在我收到如下错误:

Started PUT "/admin/courses/11111?hide=true" for ::1 at 2017-08-24 12:57:49 +0800
Processing by Admin::CoursesController#update as JS
  Parameters: {"hide"=>"true", "id"=>"11111"}
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 21808  ORDER BY `users`.`id` ASC LIMIT 1
  Course Load (0.4ms)  SELECT  `courses`.* FROM `courses` WHERE `courses`.`id` = 11111 LIMIT 1
Completed 500 Internal Server Error in 17ms (ActiveRecord: 2.1ms)

NoMethodError - undefined method `ref' for nil:NilClass:
  actionpack (4.2.9) lib/action_controller/metal/rendering.rb:9:in `process_action'
  actionpack (4.2.9) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.2.9) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.9) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
  activesupport (4.2.9) lib/active_support/callbacks.rb:505:in `call'
  activesupport (4.2.9) lib/active_support/callbacks.rb:92:in `__run_callbacks__'
  activesupport (4.2.9) lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'
  activesupport (4.2.9) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.9) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.2.9) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.2.9) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
  activesupport (4.2.9) lib/active_support/notifications.rb:164:in `block in instrument'
  activesupport (4.2.9) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.2.9) lib/active_support/notifications.rb:164:in `instrument'
  actionpack (4.2.9) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.2.9) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  activerecord (4.2.9) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.2.9) lib/abstract_controller/base.rb:137:in `process'
  actionview (4.2.9) lib/action_view/rendering.rb:30:in `process'
  actionpack (4.2.9) lib/action_controller/metal.rb:196:in `dispatch'
  actionpack (4.2.9) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.2.9) lib/action_controller/metal.rb:237:in `block in action'
  actionpack (4.2.9) lib/action_dispatch/routing/route_set.rb:74:in `dispatch'
  actionpack (4.2.9) lib/action_dispatch/routing/route_set.rb:43:in `serve'
  actionpack (4.2.9) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.9) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.9) lib/action_dispatch/routing/route_set.rb:817:in `call'

也许问题出在 actionpack (4.2.9) lib/action_controller/metal/rendering.rb:9:in process_action.

深入研究 actionpack 后,我发现 process_action 定义为:

# Before processing, set the request formats in current controller formats.
def process_action(*) #:nodoc:
  self.formats = request.formats.map(&:ref).compact
  super
end

所以这意味着来自ajax的请求无法获得格式。 我继续打印 request.format & request.formats,第一个显示 text/javascript,但第二个什么也没显示。 我不知道为什么 request.formats 不见了。

我也升级了 jquery-rails 到 4.1.1(与 ajax 相关的那个),但是没有成功。

有谁知道这方面的,请指教。非常感谢:)


信息


经过长时间的测试,我发现你应该在路径助手中添加format::js

<%= link_to("hide", admin_course_path(id: course.id, hide: "true", format: :js), remote: true, method: :put) %>

会自动转换为/admin/course/:id.js,不会出错!