How to convert Rails dynamic routes for Rails 5.2 - ruby-on-rails

I have a legacy Rails app which started life in Rails 1.2.
It has been converted through to Rails 5.0 over the years
The routes.rb file contains only two lines of 'wildcard routes' as follows
match ':controller(/:action(/:id))',:constraints => {:controller => /admin\/[^\/]+/}, :via => :all
match '/:controller(/:action(/:id))(.:format)', :via => :all
Links within the application are codedas in the following example:
<%= link_to('Marital Status', {:controller => 'marital_status', :action => 'list'}) %>
It appears that this sort of route is deprecated and will be removed in Rails 5.2
My question is how can I convert the routes to something that is acceptable to Rails 5.2.
Bear in mind that the application has about 150 controllers with a corresponding large number of actions.

I am in a similar boat and for the time being I made a rake task to generate all of the routes and write them to the routes.rb file.
Using a little ruby meta-programming its pretty straight forward to find all the methods available to a class <controller>.instance_methods then filter out all of the built in rails methods + those inherited from the application controller.
update:
I used a rake task to generate routes and put the following code in the bottom of the routes file to log when a route was not found in production:
match '/:controller(/:action(/:id))(.:format)', :via => :all, :to => proc { |env|
route = env["action_dispatch.request.path_parameters"]
Rails.logger.error("******************************************************************************************************")
Rails.logger.error("ROUTE NOT FOUND. USING WILDCARD ROUTE. REQUIRED ROUTE IS:>")
Rails.logger.error("#{env['REQUEST_METHOD'].downcase} #{route[:controller]}/#{route[:action]} => #{route[:controller]}##{route[:action]}")
Rails.logger.error("******************************************************************************************************")
controller = eval("#{route[:controller].camelize}Controller")
action = route[:action]
controller.action(action).call(env)}

Because match method has been deprecated, use get for GET and post for POST.
eg. get '/list', to: 'marital_status#list'

Related

Rails 4 and Jammit routing issue - should not use match

I've upgraded to Rails 4.0.5 and i'm using Jammit 0.6.6.
When starting the server i get an error :
/home/haimh/.rvm/gems/ruby-2.1.0/gems/actionpack-4.0.5/lib/action dispatch/routing/mapper.rb:191:in normalize_condition!:You should not use the match method in your router without specifying an HTTP method.
Looking at the stack trace i see that Jammit's routes.rb file is using the old routing API.
Is there any way of resolving this issue, beside updating the code manually in Jammit's routes.rb file?
use the via
like this:
adding , via => [:get, :post] to the end
match ':controller(/:action(/:id))' , :controller=> /admin\/[^\/]+/, :via => [:get,:post]
if you dont want to use match , you will have to have your routes inside the
resources :controller do
get :action, :on => :collection
end

Rails 4: You should not use the `match` method in your router without specifying an HTTP method

Okay, so I've upgraded to Rails 4 (kind of unplanned with my 10.9 server update) and have been able to get everything running on my photo gallery app except for the routes. For some reason I've always had trouble understanding routes since rails 3. Here was my previous working code under Rails 3
root :to => "gallery#index", :as => "gallery"
get 'gallery' => 'gallery#index'
resources :galleries
match 'gallery_:id' => 'gallery#show', :as => 'gallery'
I understand that match has been depreciated, but if I try to use GET, I'm getting the following error:
Invalid route name, already in use: 'gallery' 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.
Basically, I want the root (index) to load as "/photos/gallery" as it does, and my show action to load, for example, record id 435 as: "/photos/gallery_435" which is how I previously had it working. Sorry for what is probably a simple question, I just cannot seem to grasp the rails routing.
Try this
match 'gallery_:id' => 'gallery#show', :via => [:get], :as => 'gallery_show'
You can then refer to this path as gallery_show_path in your helpers and views.
Changing the 'as' removes the conflict.

How to translate root specific resource declaration from Rails 2 to Rails 3?

I'm migrating an application from Rails 2.3.5 to Rails 3.2.8.
I have this route from the Rails 2 app that is giving me headaches:
map.resources :soumission_vt,
:path_prefix => "/soumission/VT/:page_id", :as => 'police/:action/:id',
:requirements => {:page_id => /\S+/}
wich generates the following:
soumission_vt_index GET /soumission/VT/:page_id/police/:action/:id(.:format) {:controller=>"soumission_vt"}
POST /soumission/VT/:page_id/police/:action/:id(.:format) {:controller=>"soumission_vt"}
new_soumission_vt GET /soumission/VT/:page_id/police/:action/:id/new(.:format) {:controller=>"soumission_vt"}
edit_soumission_vt GET /soumission/VT/:page_id/police/:action/:id/:id/edit(.:format) {:controller=>"soumission_vt"}
soumission_vt GET /soumission/VT/:page_id/police/:action/:id/:id(.:format) {:controller=>"soumission_vt"}
PUT /soumission/VT/:page_id/police/:action/:id/:id(.:format) {:controller=>"soumission_vt"}
DELETE /soumission/VT/:page_id/police/:action/:id/:id(.:format) {:controller=>"soumission_vt"}
I translated it this way in Rails 3:
scope '/soumission/VT/:page_id', :constraints => {:page_id => /\S+/} do
resources :soumission_vt, :as => 'police/:action/:id'
end
but I am getting an Invalid route name: 'police/:action/:id_index'...
So is there a way to reproduce those routes in Rails 3?
Thanks!
After one try, I succeeded to make it work with the following lines of code:
scope '/soumission/VT/:page_id' do
get 'police/new', controller: :soumission_vt, action: :new, as: :new_soumission_vt
end
Hope this will help you finish your migration in time !
;)

Change paths for link_to missing out the model name

I've managed to get my routes set up (with help from these questions Routing without the model name and Permalinks with Ruby on Rails (dynamic routes)) so that articles can be accessed via my-domain/permalink rather than my-domain/articles/permalink or, the original my-domain/articles/id
Now I would like to make the paths that the link_to helper gives point to /permalink rather than /articles/permalink. I've looked at http://guides.rubyonrails.org/routing.html#overriding-the-named-helpers and see how I could redirect to eg. /images/permalink, but can't see how to have no model name present.
Can anyone suggest a way to do this?
Using :as on a match ... line in your routes file will make this work (it operates a little differently from using :as on a resources ... line):
match '/:id' => 'articles#show', :as => "article_permalink", :via => 'get'
Then you can do:
link_to "Show", article_permalink_path(article)
See Naming Routes in the Rails Guides

Does Rails 3.x change link_to behavior when link target is an ActiveRecord object?

I'm upgrading my Ruby on Rails application from Rails 2.3.11 to 3.1.1. After updating my routes file with the new syntax, I'm seeing a change in behavior of the link_to method when passing an ActiveRecord object as the link destination.
Here is an example of an old (non-RESTful) route from my 2.3 application's routes.rb:
map.with_options :controller => 'widget' do |widget|
widget.widget 'widget/show/:id', :action => 'show'
end
Here is what this route became in my 3.1 file:
scope "widget", :controller => :widget do
match "show/:id", :action => "show", :as => :widget
end
end
The output of rake routes is similar. 2.3:
widget /widget/show(/:id) {:controller=>"widget", :action=>"show"}
3.1:
widget /widget/show/:id(.:format) {:action=>"show", :controller=>"widget"}
What's different is that now my link_to calls that look like this:
link_to("Text", #widget_object)
Produce this error message:
Routing Error: No route matches { :controller=>"widget", :action=>"show", :id=>#<Widget id: 123, .....> }
After seeing this passage in the Rails Guides:
<%= link_to "Magazine details", #magazine %>...This allows you to treat instances of your models as URLs, and is a key advantage to using the resourceful style."
my guess is that Rails 2.3 happily handled my link_tos because my route's name was "widget" (changing the name would cause my 2.3 app's link_tos to break as well), but Rails 3 insists on RESTful/resourceful routes if you're going to use this link_to style.
Is that right? I've started refactoring and adding the necessary RESTful routes to make my link_tos work again — with good results — but I want to confirm that I really understand the problem. I opened a thread on the rubyonrails-talk list but have had no replies yet.
As you're not using the regular set up for your Widget resource, which would be:
resources :widgets
Rails doesn't where know where the url for #magazine should point. You need to be explicit:
link_to "Text", widget_path(#widget_object)

Resources