David Unric
David Unric

Reputation: 7719

Route override doubles records

I'd like to override a default path of an Spree/Rails extension.

The extension spree_contact_us defines default route in it's config/routes.rb this way:

Spree::Core::Engine.routes.draw do
  resources :contacts,
    :controller => 'contact_us/contacts',
    :only       => [:new, :create]
  match 'contact-us' => 'contact_us/contacts#new', :as => :contact_us
end

In the routes table there is just one record for route named contact-us:

contact_us  /contact-us(.:format)  spree/contact_us/contacts#new

If I pass following override in main application's config/routes.rb to routes.prepend method

Spree::Core::Engine.routes.prepend do
  match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us
end

rake routes displays routes to a new named path twice, when passed to routes.append even three times:

contact_us  /napiste-nam(.:format)  spree/contact_us/contacts#new
contact_us  /napiste-nam(.:format)  spree/contact_us/contacts#new

Can anybody explain this behaviour ?

Upvotes: 0

Views: 825

Answers (2)

alexandrecosta
alexandrecosta

Reputation: 3288

Using

Spree::Core::Engine.routes.draw

instead of

Spree::Core::Engine.routes.prepend

solved the routes duplication problem for me.

Upvotes: 1

engineersmnky
engineersmnky

Reputation: 29308

The problem here is that you will be creating an ambiguous named route :contact_us which when referenced by contact_us_path will return the path for the last entry in routes because you are redefining it.

The duplication does seem strange but I have not looked at how spree handles these things. In order to avoid this you could rename the secondary route such as

Spree::Core::Engine.routes.append do
  match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us_czech
end 

This should create 2 routes in which you could use contact_us_path and contact_us_czech_path which will both lead to the same place. then create a method to determine which to use.

Or just add the new route directly into the spree routing tables as (PROBABLY NOT VALID DUE TO CALL TO routes_reloader in Spree Core.

match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us
match 'contact_us' => 'contact_us/contacts#new', :as => :contact_us    

Just remember that this means that contact_us_path with always reference the second route.

Edit It seems Spree builds the default routes and then reloads them after initializing as is stated in the code

  # We need to reload the routes here due to how Spree sets them up.
  # The different facets of Spree (backend, frontend, etc.) append/prepend
  # routes to Core *after* Core has been loaded.
  #
  # So we wait until after initialization is complete to do one final reload.
  # This then makes the appended/prepended routes available to the application.
  config.after_initialize do
    Rails.application.routes_reloader.reload!
  end

I believe this is causing the named route :contact_us to be routed to it's defined route meaning that you defined it as contact_us and then redefined it as napiste-nam and since a variable can have only 1 value it held on to the second one on reload!. Due to this fact I am not sure you can do this directly through Spree.

Upvotes: 1

Related Questions