Понимание Rails 3 reply_with

Использование нового метода respond_with ActionController... как он определяет, что делать, когда действие (сохранение) успешно, а когда нет?

Я спрашиваю, потому что я пытаюсь получить спецификацию, созданную эшафотом (см. ниже), чтобы пройти, хотя бы для того, чтобы я мог ее понять. Приложение работает нормально, но, как это ни странно, представляется, что рендеринг /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

Spec, который не работает:

#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

с этой ошибкой:

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)="">'
</top>
1 ответ

ТЛ: д-р

Добавьте хэш-код ошибки в mock:

Carrier.stub(:new) { mock_carrier(:save => false, 
 :errors => { :anything => "any value (even nil)" })}

Это приведет к желаемому поведению в respond_with.

Что здесь происходит

Добавьте это после post :create

response.code.should == "200"

Он не работает с expected: "200", got: "302". Таким образом, это перенаправление вместо рендеринга нового шаблона, когда он не должен. Куда это происходит? Дайте ему путь, который, как мы знаем, потерпит неудачу:

response.should redirect_to("/")

Теперь он терпит неудачу с Expected response to be a redirect to <http: test.host=""> but was a redirect to </http:>

Предполагается, что спецификация будет проходить путем рендеринга шаблона new, который является нормальным ходом событий после того, как save на макетном объекте Carrier возвращает false. Вместо этого respond_with заканчивается перенаправлением на show_carrier_path. Это просто неправильно. Но почему?

После некоторого копания в исходном коде кажется, что контроллер пытается отобразить 'carrier/create'. Такого шаблона нет, поэтому возникает исключение. Блок спасения определяет, что запрос является POST, и в хэше ошибок нет ничего, при котором контроллер перенаправляется на ресурс по умолчанию, который является макетом Carrier.

Это озадачивает, так как контроллер не должен предполагать наличие действительного экземпляра модели. В конце концов, это create. На этом этапе я могу только предположить, что тестовая среда каким-то образом сочетает ярлыки.

Итак, обходной путь заключается в предоставлении фальшивого хэша ошибки. Обычно что-то было в хеше после того, как save терпит неудачу, так что любопытное имеет смысл.

licensed under cc by-sa 3.0 with attribution.