我需要在 foo_path 中添加一个简单的更改,所以我这样做了:
module ApplicationHelper
# [...]
def foo_path(foo, options = {})
options.merge!(bar: foo.some_attribute)
super
end
# [...]
end
现在,这在从视图调用时有效,但是当从控制器调用时,会使用没有添加内容的原始变体。
如何在应用程序范围内覆盖相应的帮助程序(_path / _url)?
答案 0 :(得分:10)
我认为实现这一目标的最简洁方法是自定义routes.rb
文件(至少对于静态默认参数)。文档:http://guides.rubyonrails.org/routing.html#customizing-resourceful-routes
默认参数示例:
get "/foo(/:bar)" => "my_controller#index", defaults: { bar: "my_default" }
默认参数值示例+范围:
scope '/(:rec_type)', defaults: { rec_type: 'mammo' }, rec_type: /mammo|face/ do
resources :patients
end
其他选项(动态限制):
高级路由限制:
如果您需要更高级/动态限制,请查看本指南:http://guides.rubyonrails.org/routing.html#advanced-constraints。
覆盖default_url_options:
此外,您可以覆盖default_url_options
方法,使用路由助手自动添加一些属性(参数):http://guides.rubyonrails.org/action_controller_overview.html#default-url-options。
您可以通过在控制器中定义名为default_url_options的方法来设置URL生成的全局默认参数。这样的方法必须返回具有所需默认值的散列,其键必须是符号:
class ApplicationController < ActionController::Base
def default_url_options(options = {})
if action_name == 'foo' # or other conditions
options[:bar] = 'your_defaults' # add here your default attributes
end
options
end
end
覆盖to_param:
Rails在模型上路由系统调用to_param
以获取:id
占位符的值。 ActiveRecord::Base#to_param
返回模型的ID,但您可以在模型中重新定义该方法。例如,给定:
class Product < ActiveRecord::Base
def to_param
"#{id}-#{title}"
end
end
这将生成:/products/254-Foo
答案 1 :(得分:3)
看起来你面临着错误的方式。您最好在路线中添加:bar param,例如:
get :foo, :bar => "bar"
否则,请提供有关您问题的更多描述性详细信息。
修改强>
以下是解决方案(基本在您的帖子更新后):
class ApplicationController < ActionController::Base
def foo_path(foo, options = {})
options.merge!(bar: foo.some_attribute)
super
end
helper_method :foo_path
end
答案 2 :(得分:3)
在Rails 3和4中,路由url助手都驻留在此模块Rails.application.routes.url_helpers
中。所以我们可以包含一个模块来覆盖其中的方法。
module FooUrlHelper
def foo_path(foo, options = {})
options.merge!(bar: foo.some_attribute)
super
end
end
# Works at Rails 4.2.1
Rails.application.routes.url_helpers.send(:include, FooUrlHelper)
# For Rails 4.2.6, I thought the following worked, but there seems to be issues, don't have time to figure out a solution yet
Rails.application.routes.named_routes.url_helpers_module.send(:include, FooUrlHelper)
你可以把它放在初始化器里面
我在控制台和控制器中试过这个并且似乎工作正常。
答案 3 :(得分:2)
正如当前的答案所示,您没有覆盖rails帮助程序(在app/helpers
文件夹中的某处定义),而是覆盖路由帮助程序(在config/routes.rb
中定义)。
从视图中调用方法foo_path
是有效的,因为在查看可用的路由助手方法之前,第一个Rails将查看所有可用的应用程序助手方法。
从控制器调用该方法不起作用,因为Rails只会通过可用的路由助手方法,而不是通过路由助手。
如果要从控制器调用应用程序助手,请在控制器中使用:
view_context.foo_path(...)
这要求您在每个控制器内对view_context.
的每次调用前加foo_path
,因此它不是一个完美的解决方案,但它应该有效。