2014-01-17 102 views
0

通過瀏覽器的請求只需要它的HTTP方法,Rails根據定義的路由將它分派給適當的控制器動作。那麼,爲什麼xhr不能做到這一點?爲什麼xml_http_request需要一個操作作爲其參數?

http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-xml_http_request

下面的代碼是從Hartl's rails tutorial

路由定義爲關係摘錄資源

SampleApp::Application.routes.draw do 
    resources :relationships, only: [:create, :destroy] 
end 

# relationships POST /relationships(.:format)  relationships#create 
# relationship DELETE /relationships/:id(.:format) relationships#destroy 

控制器

class RelationshipsController < ApplicationController 

    def create 
    @user = User.find(params[:relationship][:followed_id]) 
    current_user.follow!(@user) 
    respond_to do |format| 
     format.html { redirect_to @user } 
     format.js 
    end 
    end 

end 

在它發送POST請求的視圖模板的表單導致創建新關係,創建關係後,此表單消失,而出現另一個帶有「取消關注」按鈕的表單。

<%= form_for(current_user.relationships.build(followed_id: @user.id)) do |f| %> 
    <div><%= f.hidden_field :followed_id %></div> 
    <%= f.submit "Follow" %> 
<% end %> 

這種形式只是發送POST請求/relationships。由於Rails將其路由到relationships#create(使用params [:relationship] [:followed_id]),因此無需在此處指定操作。

規範導致通過瀏覽器發送POST請求。

it "should increment the followed user count" do 
    expect do 
    click_button "Follow" 
    end.to change(user.followed_users, :count).by(1) 
end 

使用Ajax

形式

<%= form_for(current_user.relationships.build(followed_id: @user.id), 
      remote: true) do |f| %> 
    <div><%= f.hidden_field :followed_id %></div> 
    <%= f.submit "Follow", class: "btn btn-large btn-primary" %> 
<% end %> 

規範與xhr

it "should increment the Relationship count" do 
    expect do 
    xhr :post, :create, relationship: { followed_id: other_user.id } 
    end.to change(Relationship, :count).by(1) 
end 

所以,我不知道爲什麼

xhr :post, :create, relationship: { followed_id: other_user.id } 

需要:create?我傾向於認爲發送POST請求到/relationship與相關的對象就足夠了,即使是xhr

顯然這種困惑來自於我如何xhr作品和現在的問題必須是「如何xhr作品?爲什麼xhr甚至想:action規定?」瞭解不夠

+1

你能更清楚你想做什麼嗎?看看http://apidock.com/rails/ActionController/Integration/Session/xml_http_request,它使用稍微有用的參數名稱。 –

+0

我推測這是與路由有關 - HTTP請求被引導到特定的「控制器/動作」路由;和'xml'請求一樣。但是由於XML請求具有不同的標題,因此必須以不同的方式處理。我會再看看這個! –

回答

0

在你的情況下,xhr需要:create,因爲它似乎是控制器規格。控制器規格是一種單元測試,它們繞過路由器(不像集成測試/請求規格)。只要路由器繞過,沒有信息應該在測試中調用控制器的哪個動作,因此您必須指定方法和動作。

還有一個在ActionDispatch::Integration::RequestHelpers定義xhr方法在集成測試(要求規格)中使用:

xhr(request_method, path, parameters = nil, headers_or_env = nil) 

一旦集成測試(和請求規格)是「堆滿」測試(以及是不綁定到一個控制器),您需要提供方法和路徑到xhr,並且控制器/動作將由路由器確定。

希望它回答你的問題。

相關問題