即使format.js不在控制器上,Rails也会响应Javascript请求

时间:2017-06-18 12:40:22

标签: ruby-on-rails

在标准的脚手架Rails 5.1(或5.0)控制器中,您可以在创建操作中获得此信息:

<CourseList courses={courses} />

如您所见,那里没有Uncaught TypeError: Cannot read property 'map' of undefined at CourseList (courseList.js:20) at ReactCompositeComponent.js:305 at measureLifeCyclePerf (ReactCompositeComponent.js:75) at ReactCompositeComponentWrapper._constructComponentWithoutOwner (ReactCompositeComponent.js:304) at ReactCompositeComponentWrapper._constructComponent (ReactCompositeComponent.js:279) at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:187) at Object.mountComponent (ReactReconciler.js:45) at ReactDOMComponent.mountChildren (ReactMultiChild.js:236) at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:703) at ReactDOMComponent.mountComponent (ReactDOMComponent.js:522)

但是如果你将def create @test = Test.new(test_params) respond_to do |format| if @test.save format.html { redirect_to @test, notice: 'Test was successfully created.' } format.json { render :show, status: :created, location: @test } else format.html { render :new } format.json { render json: @test.errors, status: :unprocessable_entity } end end end 添加到表单中(或者,在Rails 5.1中,你删除将使用通过ajax发布的新默认值的format.js),表单可以工作:浏览器将通过xhr发送帖子并重定向到新创建的记录。

查看开发工具,我看到表单提交的响应是200 OK,包含以下内容:

remote: true

控制台还表示它是由Javascript处理的: local: true

问题是:如果控制器中没有Turbolinks.clearCache() Turbolinks.visit("http://localhost:3000/tests/10", {"action":"replace"}) ,Rails如何处理JS请求的响应/重定向?

我全都参与了Rails魔术,但我想知道它是如何工作的,而且我还没有看到在任何地方记录的'回退对format.html块的JS请求'。

2 个答案:

答案 0 :(得分:1)

看起来生成该响应的代码来自turbolinks-rails gem。

https://github.com/turbolinks/turbolinks-rails/blob/v5.0.1/lib/turbolinks/redirection.rb#L14

从链接代码看,turbolinks会在调用redirect_to时准备js响应,请求为XHR,而不是GET请求,turbolinks: false不是提供给redirect_to电话。

当gem存在且redirect_to真实时,Turbolink会覆盖ActionController app.config.turbolinks.auto_include

def redirect_to(url = {}, options = {})
  turbolinks = options.delete(:turbolinks)

  super.tap do
    if turbolinks != false && request.xhr? && !request.get?
      visit_location_with_turbolinks(location, turbolinks)
    else
      if request.headers["Turbolinks-Referrer"]
        store_turbolinks_location_in_session(location)
      end
    end
  end
end

答案 1 :(得分:0)

此行为由ActionView::LookupContext

打算实施

https://github.com/rails/rails/blob/master/actionview/lib/action_view/lookup_context.rb#L251

# Override formats= to expand ["*/*"] values and automatically
# add :html as fallback to :js.
def formats=(values)
  if values
    values.concat(default_formats) if values.delete "*/*".freeze
    if values == [:js]
      values << :html
      @html_fallback_for_js = true
    end
  end
  super(values)
end

有一个公开的PR可以改变这种行为,但它现在停止了:

https://github.com/rails/rails/pull/15224

关于这个其他公关有一些讨论:

https://github.com/rails/rails/pull/5892