I'm trying to use out-of-the-box spree routes, but I'm running up against an error that prevents me from migrating my database or precompiling my assets for Heroku:
rake aborted! ArgumentError: Invalid route name, already in use:
'account_link' You may have defined two routes with the same name
using the :as option, or you may be overriding a route already
defined by a resource with the same naming. For the latter, you can
restrict the routes created with resources as explained here:
https://guides.rubyonrails.org/routing.html#restricting-the-routes-created
My routes can be seen below, but I'm not doing any custom spree routes:
Rails.application.routes.draw do
# This line mounts Spree's routes at the root of your application.
# This means, any requests to URLs such as /products, will go to
# Spree::ProductsController.
# If you would like to change where this engine is mounted, simply change the
# :at option to something different.
#
# We ask that you don't use the :as option here, as Spree relies on it being
# the default of "spree".
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
# COSMETICS
get 'home/index'
root 'home#index'
get 'home/info'
get 'home/export'
get 'home/kits'
get 'kits/XR250_XR400'
get 'kits/XR600'
get 'kits/XR650L'
get 'kits/polaris_key_covers'
get 'kits/replacement'
get 'kits/rear_fenders_1'
get 'kits/rear_fenders_2'
get 'kits/graphics'
get 'other/xr400mx'
# PHOTOS
resources :photos
put "photos/:id/approve" => "photos#approve", as: "approve_photo"
put "photos/:id/unapprove" => "photos#unapprove", as: "unapprove_photo"
# CONTACT US
resources :contacts
put "contacts/:id/archive" => "contacts#archive", as: "archive_contact"
put "contacts/:id/unarchive" => "contacts#unarchive", as: "unarchive_contact"
get 'admin/blogs'
post 'uploader/image', to: 'uploader#image'
get 'admin/resources'
get 'admin/subcategories'
get 'admin/subscribers'
resources :blogs
resources :lead_magnets
resources :subscribers
resources :subcategories
mount Spree::Core::Engine, at: '/store', as: 'spree'
end
When I try to push to Heroku it shows the error is somewhere inside railties?
remote: Running: rake assets:precompile remote:
DEPRECATION WARNING: Single arity template handlers are deprecated.
Template handlers must remote: now accept two parameters, the
view object and the source for the view object. remote: Change:
remote: >> Coffee::Rails::TemplateHandler.call(template)
remote: To: remote: >>
Coffee::Rails::TemplateHandler.call(template, source) remote:
(called from at /tmp/build_3e42be0e/Rakefile:6) remote:
rake aborted! remote: ArgumentError: Invalid route name,
already in use: 'account_link' remote: You may have defined
two routes with the same name using the :as option, or you may be
overriding a route already defined by a resource with the same naming.
For the latter, you can restrict the routes created with resources
as explained here: remote:
https://guides.rubyonrails.org/routing.html#restricting-the-routes-created
remote:
/tmp/build_3e42be0e/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.3.2/lib/action_dispatch/routing/route_set.rb:578:in
`add_route'
I am seriously out of my depth here. Please help!
I'm running these spree-related gems:
gem 'spree', '~> 4.0'
gem 'spree_auth_devise', '~> 4.0.0'
gem 'spree_gateway', '~> 3.6'
Related
I am setting up my Rails API server following this tutorial: building-awesome-rails-apis-part-1
Everything works well, except the part that mentions that it is not necessary to indicate the namespace in the route. Eg.
Now our URls look like: http://api.example.com/v1/people or just
http://api.example.com/people if you don’t use the version, it
doesn’t interfere with your regular people routes, and it looks great.
When I call http://api.mydomain.com/v1/therapists/ it works, but when I try to omit the v1 namespace in the URL it's not working, do I need to do any extra configuration?
I'm using Rails 6.0.3.4
This is my specific routes.rb file:
Rails.application.routes.draw do
namespace :api, :path => "", :constraints => {:subdomain => "api"} do
namespace :v1 do
resources :therapists do
resources :appointments
end
end
end
end
Solution
As zhisme suggested, I used rack-rewrite gem to do what I wanted.
First, I added the gem to my Gemfile:
gem 'rack-rewrite', '~> 1.5', '>= 1.5.1'
After that I added the configuration in config/application.rb file
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
rewrite '/therapists', '/v1/therapists'
end
And it worked.
In order to achieve this, you will need to insert inside Rack code. There is a gem rack-rewrite that can do redirects before Rails code execute, thus before rails routes resolving. Check their README for installation.
so modifying README example to your question, you can do something like
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
rewrite '/api/therapists/appointments', '/api/v1/therapists/appointments'
end
or you can make redirects to give your api consumers to know that correct url is a bit different
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
moved_permanently '/api/therapists/appointments', '/api/v1/therapists/appointments'
end
There is quite good article describing different solutions, take a look for more details.
If you omit the v1 namespace in the URL, you must also remove it from your routes.rb file.
The quote from the tutorial stated "or just http://api.example.com/people if you don’t use the version", meaning if you don't include the v1 namespace in the routes.rb file.
I have an application my_app, and an engine my_engine.
my_app routes:
Rails.application.routes.draw do
mount MyEngine::Engine => "/api"
end
my_engine routes:
MyEngine::Engine.routes.draw do
post "files/sync" => "files#sync"
end
From my_app, I run rails routes, and see the following:
Prefix Verb URI Pattern Controller#Action
my_engine_engine /api MyEngine::Engine
Routes for MyEngine::Engine:
As you can see, Routes for MyEngine::Engine: displays 0 results. I've tried every answer in the books about this issue, but nothing works.
Why are my engine routes not being listed by the app?
(Note that my_engine is a local gem — do I have to do something special to reload it possibly?)
One solution turned out to be changing:
gem 'my_engine', path: '/Users/me/Desktop/my_engine_gem'
to:
gem 'my_engine', path: '/Users/me/Desktop/my_engine_gem', require: 'my_engine'
This worked, even though placing require 'my_engine' in an initializer did not work. Not sure what the distinction is.
When I am doing rake db:migrate I am getting the below error.
rake aborted! NameError: uninitialized constant RailsAdmi
I checked an answer where It is said that there's some path set for rails admin in the routes file, I need to remove the same from it.
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users
resources :users
This is part of my route file. Even If I am removing this line, I am getting the same error.
In another answer It said to upgrade rails, I did that as well, but it gives same error.
Please help.
I've been creating a gem and I need to create a route that maps to a controller in the gem.
I have a file ( config/routes.rb ) which looks like this:
Rails.application.routes.draw do
match "rest/*path" => "bconnected/apis#rest"
end
My controller lives in *app/controllers/bconnected/apis_controller.rb*
My gemspecs file includes all of these files.
I run gem build, and gem install.
I include my gem in the rails Gemfile but when I try to hit that URL I get:
No route matches [GET] "/rest/test"'
Do I need to do anything special for Rails to read my routes.rb file from the gem?
I have the following in my routes.rb file for Rails 3:
13 namespace :user do
14 root :to => "users#profile"
15 end
I get this error on heroku:
ActionController::RoutingError (uninitialized constant User::UsersController):
I already restarted the application.
I am doing this because I am using devise and this is what it says on the wiki:
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-on-successful-sign-in
The problem is that Rails is expecting there to be a controller within a module called Users because that's what namespace :user infers. Perhaps you meant to use scope instead of namespace?
scope :path => "user" do
root :to => "users#profile"
end
Note: in this situation if you've only got one route it would not be wise to use scope, but if you've got multiple ones with the /user prefix then it would be fine to. If you only had one, I would do this instead:
get '/user', :to => "users#profile"
Heroku environments run in production mode. When you run locally, you run in development mode, which accounts for at least one difference. Try this instead:
RAILS_ENV=production bundle exec rails s
and see if you notice the same error.