2010-12-15 8 views
12

ActionController의 새로운 respond_with 메소드 사용 ... 작업 (저장)이 성공할 때와 렌더링되지 않을 때 어떻게 렌더링할지 결정하는 방법은 무엇입니까?Rails 3의 respond_with에 대한 이해

내가 이해할 수 있도록하기 위해 (아래에 포함 된) 발판 생성 된 스팩을 얻으려고하기 때문에 물어 본다. 응용 프로그램은 정상적으로 작동하지만 이상하게도 유효성 검사가 실패하면 /carriers (브라우저의 URL이 말하는 것 이상)이 렌더링 된 것으로 보입니다. 그러나이 사양은 "new"이 될 것으로 예상됩니다 (그 문제는 제가 그렇습니다). 대신 <"">을 받고 있습니다. 사양이 "" 일 것으로 예상되는 것으로 변경하면 여전히 실패합니다.

/carriers을 렌더링하면 해당 페이지에서 유효성 검사에 실패한 필드 옆에 error_messages가 표시됩니다.

respond_with에 익숙한 사람이라면 어떻게 될까요?

#carrier.rb 
    validates :name, :presence => true 

#carriers_controller.rb 
class CarriersController < ApplicationController 
    respond_to :html, :json 

... 

    def new 
    respond_with(@carrier = Carrier.new) 
    end 

    def create 
    @carrier = Carrier.new(params[:carrier]) 
    flash[:success] = 'Carrier was successfully created.' if @carrier.save 
    respond_with(@carrier) 
    end 

사양 실패 사용자들은 :

1) CarriersController POST create with invalid params re-renders the 'new' template 
    Failure/Error: response.should render_template("new") 
    expecting <"new"> but rendering with <"">. 
    Expected block to return true value. 
    # (eval):2:in `assert_block' 
    # ./spec/controllers/carriers_controller_spec.rb:81:in `block (4 levels) in <top (required)>' 
+1

반송파 컨트롤러의'# new' 및'# create' 작업에서 모두'Carrier.new'를 호출합니다. 나는'def create' 액션 메소드에서'Carrier.create (params [: carrier])'가되어야한다고 생각합니다. – Ernesto

답변

23

TL : 박사

모의에 오류 해시를 추가

012이 오류와

#carriers_controller_spec.rb 
require 'spec_helper' 

describe CarriersController do 

    def mock_carrier(stubs={}) 
    (@mock_carrier ||= mock_model(Carrier).as_null_object).tap do |carrier| 
     carrier.stub(stubs) unless stubs.empty? 
    end 
    end 


    describe "POST create" do 
    describe "with invalid params" do 
     it "re-renders the 'new' template" do 
     Carrier.stub(:new) { mock_carrier(:save => false) } 
     post :create, :carrier => {} 
     response.should render_template("new") 
     end 
    end 
    end 
end 

이렇게하면 respond_with에서 원하는 동작이 트리거됩니다.

여기 무슨 일

그것은 expected: "200", got: "302"에 실패 post :create

response.code.should == "200" 

후이를 추가합니다. 따라서 새 템플릿을 렌더링하지 말고 리디렉션합니다. 어디가는거야?

response.should redirect_to("/") 

을 지금은 스펙이 모의에 save 후 이벤트의 정상적인 과정 인 new 템플릿을 렌더링 통과하도록되어 Expected response to be a redirect to <http://test.host/> but was a redirect to <http://test.host/carriers/1001>

실패 : 그것은 우리가 실패합니다 알고있는 경로를 제공 Carrier 객체는 false를 반환합니다. 대신 respond_withshow_carrier_path으로 리디렉션됩니다. 어느 쪽이 틀림없이 잘못입니다. 하지만 왜?

소스 코드를 파고 들자 컨트롤러가 '통신 업체/생성'을 렌더링하는 것으로 보입니다. 템플릿이 없으므로 예외가 발생합니다. 응급 구조 블록은 요청이 POST이고 오류 해시에 컨트롤러가 모의 Carrier이라는 기본 리소스로 리디렉션되는 것이 없음을 확인합니다.

컨트롤러가 유효한 모델 인스턴스가 있다고 가정해서는 안되는 것이 당혹 스럽습니다. 결국 create입니다. 이 시점에서 나는 테스트 환경이 어떻게 든 지름길을 취하고 있다고 추측 할 수 있습니다.

그래서 해결 방법은 가짜 오류 해시를 제공하는 것입니다. save이 실패한 후 일반적으로 해시가 될 수 있으므로 이해가됩니다.

+0

멋지게 완료되었습니다! 이걸 버그라고 생각하니? 필자는 아직 레일즈에 대해 충분히 알지 못한다. 하지만 당신의 대답은 내가 배우는 것을 돕고 있습니다! 다시 한 번 감사드립니다 ... – Meltemi

관련 문제