How can I globally override a rails url helper?

ruby-on-rails

Solution

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`

Problem

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?

Original source