Rails 3.2 Engines - routes not working in test cases

我的未来我决定 提交于 2019-12-24 06:00:57

问题


I mounted in my app the RailsAdmin engine ( according to the instructions from the wiki ) using

mount RailsAdmin::Engine => '/backend', :as => 'rails_admin'

I had to extend one controller from the engine to add a before_filter. When running my app in development, my extension and the other engine features are working perfectly.

However I have an issue in writing functional tests using Test::Unit for my before_filter. The filter kicks in at the right moment and works as expected, but once the action "tweaked" by the before filter redirects to index ( which is an expected result ), I get the following routing error:

ActionController::RoutingError: No route matches {:controller=>"rails_admin/main"}

The code leading to the exception lies in the engine's method to redirect to index or to the previous page ( kind of referer ); here is the code for the method

def back_or_index

if params[:return_to].presence

params[:return_to]

else

index_path

end

I discovered that when running the app in development, the url_for call triggered by index_path is supplied with the proper path_segments ( i.e.: :model_name => 'user' ) so that the route below is matched

   index GET|POST    /:model_name(.:format)                 rails_admin/main#index

On the other hand, when running the tests, the path_segments are not supplied, thus the :model_name constraint is not satisfied when looking for a matching route.

Since I'm new to engines, can someone tell me what I'm missing?

To me it looks as if the engine should take into consideration the fact that is mounted generating the index_path, but as I said I'm not an expert in this....


回答1:


use_route was not enough: the call to index_path was failing anyway.

After lots of debugging, I am not yet completely sure about the root cause of why the same code was not working both in test and development.

What I observed is that index_path in development is able to infer the model_name from the url of the request, while in test is is not.

Although ugly, my solution was to override the method as follows in app/controllers/rails_admin/main_controller.rb

module RailsAdmin
 class MainController

        # Override to fix a routing error when running tests
    def back_or_index
      if params[:return_to].presence && params[:return_to].include?(request.host) && (params[:return_to] != request.fullpath)
        params[:return_to]
      else
        # forward :model_name as default_url_options is not aware of it in tests
        index_path( :model_name => params[:model_name] )
      end
    end

 end
end

In my controller specs for MainController I do the following

put :edit, { :model_name => 'user', :id => root.id, :user => { :role => :root }, :use_route => :rails_admin }

And this is what I have in my routes

  devise_for :users
  mount RailsAdmin::Engine => '/backend', :as => 'rails_admin'
  mount Rich::Engine => '/rich', :as => 'rich'

If anyone has a better solution, sharing would be really appreciated!



来源:https://stackoverflow.com/questions/14281505/rails-3-2-engines-routes-not-working-in-test-cases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!