覆盖 Rails 3 引擎提供的命名路由
我正在开发一个使用 Rails 引擎的 Ruby on Rails 3(.0) 应用程序。但是,在我的本地应用程序中,我想覆盖 Rails 引擎提供的路由之一。
从引擎 config/routes.rb:
match 'their_named_route' => 'controller#action', :as => 'the_route'
从我的应用程序 config/routes.rb:
match 'my_named_route' => 'controller#action', :as => 'the_route'
但是,当我检查路线时,两者似乎都处于活动状态(并且它们的路线似乎“获胜”,至少在引擎控制器内
$ rake routes
the_route /my_named_route(.:format) {:controller=>"controller", :action=>"action"}
the_route /their_named_route(.:format) {:controller=>"controller", :action=>"action"}
)强制本地应用程序的命名路由优先的好方法?
I am working on a Ruby on Rails 3(.0) application that uses a Rails engine. However, in my local application, I want to override one of the routes provided by the Rails engine.
From the engine config/routes.rb:
match 'their_named_route' => 'controller#action', :as => 'the_route'
From my application config/routes.rb:
match 'my_named_route' => 'controller#action', :as => 'the_route'
However, when I inspect the routes, both seem to be active (and their route appears to "win", at least within the engine controllers)
$ rake routes
the_route /my_named_route(.:format) {:controller=>"controller", :action=>"action"}
the_route /their_named_route(.:format) {:controller=>"controller", :action=>"action"}
Is there a good way to force my local application's named route to take priority?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我通过将引擎的路由从 config/routes.rb 移动到引擎类本身的类方法来解决这个问题:
然后在基本应用程序的路由文件中:
然后我可以愉快地用引擎中的路由覆盖基本应用程序中的任何路由。
请注意,覆盖路由需要在被覆盖路由之前定义,因为较早定义的路由优先于较晚定义的路由。
I got around this by moving my engine's routes from config/routes.rb to a class method in the engine class itself:
and then in the base app's routes file:
I can then happily override any routes in the base app with those in the engine.
Note that the overriding routes need to be defined before the overridden routes since the earlier defined routes take precedence over later ones.
恐怕没有这么简单的方法。路由在 lib/action_dispatch/routing/mapper.rb:271 中定义,它调用 RouteSet 上的 add_route(在rack-mount-0.6.14/lib/rack/mount/ 中定义) route_set.rb,并在第 71 行附加了名称)。没有remove_route方法,引擎的路由是最后添加的。您可以在使用 Rails.application.routes.draw 初始化应用程序后手动添加路线,而不是将其放在 paths.rb 中,或者您可以修补引擎。
I'm afraid that there's no such easy way. The routes are defined in
lib/action_dispatch/routing/mapper.rb:271
, which calls add_route on the RouteSet (defined inrack-mount-0.6.14/lib/rack/mount/route_set.rb
, and on line 71 the name is attached). There's no remove_route method, and the Engine's route is added last. You can add your route manually after the application is initialized with Rails.application.routes.draw instead of having it in routes.rb, or you can patch the Engine.无法覆盖引擎内的路线。相反,您必须定义一条否决路线。您可以通过在引擎的路由器上调用
prepend
来完成此操作:如果引擎的命名空间是隔离的,则这将使用引擎命名空间内部的
SomewhereController
。如果没有,它将使用典型的SomewhereController
。如果你想覆盖路由以返回 404,我能想到的最好方法是重定向到 404 页面:
There is no way to override a route within an engine. Instead, you must define an overruling route. You can do this by calling
prepend
on the engine's router:If the engine's namespace is isolated, this will use the
SomewhereController
from inside the engine's namespace. If not, it will use the typicalSomewhereController
.If you want to override a route to return a 404, the best way I can think of is to redirect to a 404 page:
您需要将初始值设定项挂钩添加到 config/application.rb,如下所示:
首先加载引擎的 roues.rb,您可以覆盖它们的路由。
You need add initializer hook to config/application.rb, like this:
It's load roues.rb of you engine first and you can override their routes.
您可以按照上面 Ryan Bigg 的建议预先添加路线。我发现为了用我的自定义路由推翻命名路由助手,我需要调用
append
而不是prepend
,如下所示:否则应用程序包含路由和命名助手for 引擎的路由器是最后一个定义,因此也是应用的定义。
You can prepend routes as suggest by Ryan Bigg above. I found that in order overrule the named route helper with my custom route I need to call
append
instead ofprepend
, like so:Otherwise the app contains both routes and the named helper for engine's router is the last definition, and therefore the one that is applied.
在routes.rb中定义的路由规则从上到下应用,直到找到匹配。我只需将较高优先级的规则移动到安装引擎的行上方即可覆盖已安装引擎中定义的路线。所以,
导致应用程序将 /about/ 请求路由到(在本例中)静态控制器,而:
导致应用程序将 /about/ 请求路由到已安装引擎中定义的路由。
Routing rules defined in routes.rb are applied from the top down until a match is found. I was able to override the route defined in the mounted engine simply by moving the higher-priority rule above the line where the engine is mounted. So,
results in the app routing /about/ requests to (in this case) the static controller, whereas:
results in the app routing /about/ requests to the route defined in the mounted engine.
要替换 gem 或引擎提供的默认路由路径,我们可以通过以下方式实现。
对我来说,我想将所有路线中的“spree_user”替换为“account”等
/user/spree_user/sign_in 我按照以下方式执行此操作
步骤 1
创建 config/some_engine_route_override.rb
复制引擎路由文件的内容并根据需要更新路由
第2步
在 application.rb 中使用以下钩子
To Replace the default routes path provided by gem or engine we can achive that in following way.
For me I wanted to replace 'spree_user' with 'account' etc from all routes
/user/spree_user/sign_in I did this in following way
Step 1
Create config/some_engine_route_override.rb
Copy the content of engine route file and update the routes as per need
Step 2
in application.rb use the folllowing hook