2017-06-18 51 views
3

在标准,架式的Rails 5.1(或5.0)控制器,你得到这个在创建行动:Rails的响应请求的Javascript即使format.js不在控制器

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 

正如你看到的,有那里没有format.js。如果你添加remote: true到表单中(或者,在Rails 5.1中,你删除了local: true,它将使用新的默认值,通过ajax发布),表单工作:浏览器将通过xhr发送一个帖子,重定向到新创建的记录。

综观开发工具,我看到的表单提交的响应是200 OK,内容如下:

Turbolinks.clearCache() 
Turbolinks.visit("http://localhost:3000/tests/10", {"action":"replace"}) 

控制台也表明它是由Java脚本处理: Started POST "/tests" for 127.0.0.1 at 2017-06-18 09:38:25 -0300 Processing by TestsController#create as JS

的问题是:如果控制器中没有format.js,Rails如何处理JS请求的响应/重定向?

我全身心投入Rails魔术,但我想知道这是如何工作的,而且我还没有看到这个'回退JS请求format.html块'在任何地方记录。

回答

1

它看起来像生成该响应的代码来自turbolinks-rails宝石。

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通话。

Turbolinks覆盖ActionController redirect_to当宝石存在和app.config.turbolinks.auto_include是truthy。

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 
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