My Rails route sometimes get a not found error and resolves itself after a few seconds.
undefined local variable or method owner_root_path' for #<Owner::SessionsController:0x00007f30408d46f0>
/myapp/app/controllers/owner/sessions_controller.rb:30:increate’
/ruby/2.5.0/gems/actionpack-5.1.6.2/lib/action_controller/metal/basic_implicit_render.rb:4:in send_action'
/ruby/2.5.0/gems/actionpack-5.1.6.2/lib/abstract_controller/base.rb:186:inprocess_action’
My routes config
# routes/owner.rb
Rails.application.routes.draw do
constraints subdomain: /^owner/ do
root to: "owner/top_pages#show", as: :owner_root
...
end
end
# application.rb
config.paths["config/routes.rb"] = %w(
config/routes/owner.rb
config/routes.rb
).map {|relative_path| Rails.root.join(relative_path)}
Does anyone know why it happened?
Rails 6.1 guides introduced the draw macro which can be used to split a large route file into smaller files. You can read about it here: Breaking up very large route file into multiple small ones
I don't know whether your version of Rails supports this macro. If it doesn't, then you can easily define a draw method yourself, using the source. It will be something like this:
def draw(routes_name)
instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
end
P.S: You should definitely check out the commit that introduced this method/macro.
Related
The following code used to work in Rails 6.0.4.8 but no longer works in 6.1.X (I tried all minor versions, even the latest 6.1.6 has this behaviour; the engine itself is legacy code, unfortunately, we can't remove it easily):
# config/routes.rb
Spree::Core::Engine.routes.named_routes.url_helpers_module.include(DynUrlHelper)
MyApp::Application.routes.draw do
mount Spree::Core::Engine, at: "/"
end
# app/helpers/dyn_url_helper.rb
module DynUrlHelper
def dyn_path(target)
# ...
end
end
It throws an undefined method error when I try to use #dyn_path in a controller or view:
undefined method `dyn_path' for #<MyController:0x00007facc9227298>
Upon investigating the issue, I noticed, that when I change a file and Zeitwerk reloads my code, it works! But a fresh started app fails. So I guess it has something to do with caching the named routes helpers?
The only thing I found is this question Rails route issue after upgrading to rails 6.1 linking to this Github issue https://github.com/rails/rails/issues/42218. But I'm not sure if it really is the same problem.
I'm playing around with a tester app using an ember frontend and using jsonapi-resources to build the rails api. My routes in the rails app are defined as follows
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
jsonapi_resources :books
jsonapi_resources :authors
jsonapi_resources :publishing_houses
end
However I've noticed something strange. If I go to the path for publishing_houses like so: http://localhost:3000/publishing_houses it says the route/page doesn't exist. However if I go to http://localhost:3000/publishing-houses with a dash instead of an underscore between publishing houses, I get the response that I want.
The problem is in my ember app, I've checked the console and it requests data using this url: http://localhost:3000/publishing_houses with the underscore, so I don't get any data back in my ember request.
Is there a reason for this behavior? Or am I doing something wrong?
I did some digging and there appears to be a config for the route format. Try this
# config/initializers/jsonapi.rb
JSONAPI.configure do |config|
config.route_format = :underscored_route
end
That should turn the routes into "/publishing_houses" instead of "publishing-houses" which would make them compatible with the other library you are using.
class UserPreview < ActionMailer::Preview
# Accessible from http://localhost:3000/rails/mailers/notifier/welcome_email
def welcome_email
UserMailer.welcome_email(User.first)
end
end
I have this simple mailer preview using Ruby on Rails 4.1.
If I comment out, all of the routes in my routes.rb file and leave only this, the mailer preview works:
MyTestApp::Application.routes.draw do
end
So obviously one of my rights is getting used before the default Rails one for mailer previews.
What do I need to type into the routes rb file?
I know this is an old question, but figured I'd post an answer anyway.
I'm guessing you have a route similar to this near the end of your routes.rb file:
match '/:controller(/:action(/:id))'
That is a 'catch all' route. The rails code appends the mailer preview routes to the end of the routes, so they are never reached due to the 'catch all' route.
It sounds like the 'catch all' route may be retired in rails 5.0? It is probably a good idea to review your routes so you don't need a 'catch all'. Here is a link to the issue where someone mentions the 'catch all' is being retired at some point: https://github.com/rails/rails/issues/15600
So, here is the fix. Use at your own risk!
Insert the mailer routes before your 'catch all'.
get '/rails/mailers' => "rails/mailers#index"
get '/rails/mailers/*path' => "rails/mailers#preview"
That will allow your mailers to work and your 'catch all' will continue working. Now, this is a complete hack which should only be used until you're able to fix the root issue, which is eliminating the need for the 'catch all' route.
I did find the following in the issues list for rails, which looks like has been accepted and merged. Not sure what version it is in, but it seems like they have updated the mailer preview code to prepend the routes instead of appending them.
https://github.com/rails/rails/pull/17896/files
Good luck!
I'm in the process of upgrading a rails 3 app to rails 4.0.1.
In my rails 3 app I have the following code in the my application.rb to use multiple route files.
config.paths["config/routes"] += Dir[Rails.root.join('config',
'routes', '*.rb').to_s]
but that throws an exception when I try to use the same thing in rails 4.
Any tips?
In one of my larger applications I use the following segment of code inside of my config/routes.rb file.
class ActionDispatch::Routing::Mapper
def draw(routes_name)
instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
end
end
YourApplication::Application.routes.draw do
# Loads config/routes/common.rb
draw :common
# Loads config/routes/another.rb
draw :another
end
Rails 4 initially had support for draw :routeName but it was removed as it did not show any improvements. (I dont know ^.^) You can check out the git commit doing so here: https://github.com/rails/rails/commit/5e7d6bba79393de0279917f93b82f3b7b176f4b5
Check out this SO answer: rails 4: split routes.rb into multiple smaller files
Looks like this ability was deprecated in Rails 4.
I don't know how big your application is. But you should look into routing concern in rails 4, if you need some proper refactoring with Rails route.
Mo' files, mo' problems.
We are updating our large web app and getting rid of our URL synonym system. For example, though we only use one model for 'advertiser', it is aliased to 'merchants' and 'sellers', using synonymous paths. Thus, /merchant/1 and /seller/1 use the same exact controller and action as advertiser/1.
We no longer need this functionality, but we do need for old URLs to correctly redirect users to the proper place (i.e. proper controller actions).
So far, I've tried:
1) reading http://guides.rubyonrails.org/routing.html - This lead me to try the following suggestions
2) match '/merchants' => redirect('/advertisers') - this didn't seem to work at all, though the syntax seems correct.
3) iterating over resources (this produces a TON of routes and may cause insecurities):
ADVERTISER_SYNONOYMS = ['affiliates', 'sellers']
ADVERTISER_SYNONYMS.each do |a|
resources :advertisers, :path => a, :as => :advertiser
resources :other_controller do
member do
get :test
match :generate_test
end
end
end
end
We use nested resources in our routes.rb, so I'm struggling with getting these synonymns to be recognized all throughout more complex URLs. If anyone dealt with this problem or has a more elegant suggestion, I'd be most grateful.
There are many ways to handle this, including additional routes in routes.rb like you've tried, or rewrites at the webserver level such as Apache or Nginx.
One solution I like is the rack-rewrite gem; it keeps routes clean and the rules are plain ruby. It provides a set of methods for configuring rewrites and redirects. For your situation, I would want to use permanent redirects. Though I haven't tested it out myself, something like the following may work for you:
# Gemfile
gem 'rack-rewrite'
# application.rb
config.middleware.use(Rack::Rewrite) do
r301 %r{/merchant|seller/(\w+)}, '/advertiser/$1'
end