Спецификацията на контролера не успява да намери маршрути, дефинирани от моя Rails двигател

Създавам Rails двигател под Rails 3.0.12, но имам проблеми с маршрутите, когато се опитвам да напиша спецификации за контролера на моя двигател.

Контекстът

Следвам оформление на Enginex. Машината се казва Featuring и не е изолирана. Той не декларира маршрути сам по себе си: няма featuring/config/routes.rb файл. Вместо това е осигурен метод routes_for_feature за основното приложение за дефиниране на специфични за двигателя маршрути.

##
# featuring/lib/featuring/rails.rb
#
require 'featuring/rails/routing'

module Featuring
  class Engine < ::Rails::Engine
  end
end

##
# featuring/lib/featuring/rails/routing.rb
#
module ActionDispatch::Routing
  class Mapper

    def routes_for_feature(feature_name)
      resource_name = feature_name.to_s.pluralize.to_sym
      resources resource_name, :controller => "featuring/features", :only => [:index, :show], :feature => feature_name.to_s
    end
  end
end

Следвайки шаблона Enginex, имам приложение Dummy, което дефинира маршрутите така:

# featuring/spec/dummy/config/routes.rb
Dummy::Application.routes.draw do
  routes_for_feature :feature_model
end

Проблемът

Всичко работи добре, когато стартирам rails сървъра за приложението Dummy. Мога да преглеждам до http://localhost:3000/feature_models и заявката е успешна.

Бих искал да спецификирам моя Featuring::FeaturesController, но не мога да го накарам да намира маршрутите.

Ето спецификацията:

# featuring/spec/controllers/features_controller_spec.rb
require 'spec_helper'

describe Featuring::FeaturesController do

  context "feature_models" do
    it "GET index should be successful" do
      puts Rails.application.routes.routes
      get :index, { :use_route => "featuring", :feature => "feature_models" }
      response.should be_success
    end
  end
end

И ето резултатът от изпълнението на тази спецификация:

rspec spec/controllers/features_controller_spec.rb:7
Featuring::FeaturesController
  feature_models
GET    /feature_models(.:format)                {:action=>"index", :controller=>"featuring/features"}
GET    /feature_models/:id(.:format)            {:action=>"show", :controller=>"featuring/features"}
    GET index should be successful (FAILED - 1)

Failures:

  1) Featuring::FeaturesController feature_models GET index should be successful
     Failure/Error: get :index, { :use_route => "featuring", :feature => "feature_models" }
     ActionController::RoutingError:
       No route matches {:feature=>"feature_models", :controller=>"featuring/features"}
     # ./spec/controllers/features_controller_spec.rb:8:in `block (3 levels) in <top (required)>'

Както можете да видите, дори ако маршрутите са правилно дефинирани, посоченият контролер изглежда не ги намира.

Нещо ме изненадва в RoutingError: No route matches {:feature=>"feature_models", :controller=>"featuring/features"}. action => "index" не се показва.


person Romain Champourlier    schedule 14.05.2012    source източник
comment
Имам този проблем и в rails 3.2.3. Знам със сигурност, че не е свързано с :action =› index, но все още съм объркан защо получавам тази RoutingError...   -  person Amiel Martin    schedule 26.09.2012


Отговори (2)


Имах подобна грешка и също бях объркан от липсата на {:action => "index"} в опциите за маршрут. Оказа се обаче, че не това е проблемът. ActionDispatch третира липсата на :action като еквивалент на {:action => "index"}. Вижте:

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set.rb#L545

Възможно е да ви липсва параметър на заявка във вашата спецификация, какъвто беше случаят с мен. Проверете реда Параметри в регистрационния файл на вашия сървър, когато заредите страницата в браузъра.

person Tyler Boyd    schedule 08.06.2012

Номерът е да добавите routes { } към спецификацията си, така:

describe Featuring::FeaturesController do
  routes { Featuring::Engine.routes }
  # ...
end

Вижте също Няма съвпадения на маршрута ... Rails Engine

person berkes    schedule 11.07.2015