我在我的应用程序中安装了RailsAdmin引擎(根据wiki的说明)使用
mount RailsAdmin::Engine => '/backend', :as => 'rails_admin'
我不得不从引擎中扩展一个控制器来添加一个 before_filter。 在开发中运行我的应用程序时,我的扩展和其他引擎功能运行良好。
但是我在使用 Test::Unit 为我的 before_filter 编写功能测试时遇到问题。 过滤器在适当的时候启动并按预期工作,但是一旦之前过滤器“调整”的操作重定向到索引(这是预期的结果),我会收到以下路由错误:
ActionController::RoutingError: 没有路由匹配 {:controller=>"rails_admin/main"}
导致异常的代码在于引擎重定向到索引或上一页的方法(一种referer);这是方法的代码
def back_or_index
如果参数[:return_to].presence
参数[:return_to]
其他
index_path
结束
我发现在开发中运行应用程序时,由 index_path 触发的 url_for 调用提供了正确的 path_segments(即::model_name => 'user') 以便匹配下面的路由
index GET|POST /:model_name(.:format) rails_admin/main#index
另一方面,在运行测试时,未提供 path_segments,因此在寻找匹配路径时不满足 :model_name 约束。
由于我是引擎新手,有人可以告诉我我缺少什么吗?
对我来说,引擎似乎应该考虑到安装生成 index_path 的事实,但正如我所说,我不是这方面的专家……
use_route 还不够:对 index_path 的调用无论如何都失败了。
经过大量调试,我还不能完全确定为什么相同的代码在 test 和 development 中都不起作用的根本原因。
我观察到的是 development 中的 index_path 能够从请求的 url 中推断出 model_name,而在 test 中则不是。
虽然丑陋,但我的解决方案是重写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
在我的 MainController 控制器规格中,我执行以下操作
put :edit, { :model_name => 'user', :id => root.id, :user => { :role => :root }, :use_route => :rails_admin }
这就是我的路线
devise_for :users
mount RailsAdmin::Engine => '/backend', :as => 'rails_admin'
mount Rich::Engine => '/rich', :as => 'rich'
如果有人有更好的解决方案,将不胜感激!
我找到了怎么做,并在这里回答了另一个问题