I needed to add a simple change to foo_path, so I did this:
module ApplicationHelper
# [...]
def foo_path(foo, options = {})
options.merge!(bar: foo.some_attribute)
super
end
# [...]
end
Now, this works when called from a view, but when called from a controller, the original variant without my additions is used.
How can I override the according helpers (_path/_url) application wide?
I think the cleanest way to achieve that is to customize routes.rb
file (at least for static default parameters). Docs: http://guides.rubyonrails.org/routing.html#customizing-resourceful-routes
Default param example:
get "/foo(/:bar)" => "my_controller#index", defaults: { bar: "my_default" }
Default param value example + scope:
scope '/(:rec_type)', defaults: { rec_type: 'mammo' }, rec_type: /mammo|face/ do
resources :patients
end
Other options (for dynamic restriccions):
Advanced routing constraints:
If you need more advanced/dynamic restrictions, take a look to this guide: http://guides.rubyonrails.org/routing.html#advanced-constraints.
Override default_url_options:
Also, you can override default_url_options
method to automatically add some attributes (params) using routes helpers: http://guides.rubyonrails.org/action_controller_overview.html#default-url-options.
You can set global default parameters for URL generation by defining a method called default_url_options in your controller. Such a method must return a hash with the desired defaults, whose keys must be symbols:
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
Override to_param:
Rails routing system calls to_param
on models to get a value for the :id
placeholder. ActiveRecord::Base#to_param
returns the id of a model, but you can redefine that method in your models. For example, given:
class Product < ActiveRecord::Base
def to_param
"#{id}-#{title}"
end
end
This would generate: /products/254-Foo
In Rails 3 and 4, route url helpers all resides in this module Rails.application.routes.url_helpers
. So we can include a module to override methods inside it.
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)
You can just place this inside initializers
I tried this in console and controller and seems to work fine.
Looks like you are facing wrong way. You would better add :bar param in your route, like:
get :foo, :bar => "bar"
Otherwise, please provide more descriptive details about your problem.
Edit.
Here is the solution(basic on your post update):
class ApplicationController < ActionController::Base
def foo_path(foo, options = {})
options.merge!(bar: foo.some_attribute)
super
end
helper_method :foo_path
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With