I'm new to Ruby on Rails and trying to learn the framework by reading Rails 3 in Action book as well as looking into different online resources. But now I'm struggling with dramatic syntax difference in what book explains, what I see in online resources and what I see in generated code. For example, I'd like to setup my custom routes in routes.rb
The book says
match '/login',
:to => "accounts#login"
Online resource says:
map.login '/login', :controller => 'accounts', :action => 'login'
Another online resource says:
match '/login' => 'accounts#login', :as => 'login'
In my case works only the last one... So the question is why syntax is so different and where to look for syntax explanation for the latest Ruby on Rails?
The first example is fine and is essentially the same as the third example. It just doesn't set up the login paths for you e.g. in your code you won't be able to reference login_path like you can with the third example (the :as => 'login' tells rails to set up the login_path helper).
The online resource (second example) is for Rails v.2.3.11 which is fairly old - we're now on v.3.2. so that resource is out of date. Here is the up to date version.
For start I recommend reading Rails Routing from the Outside In, there are very actual rails guides.
http://apidock.com is a good place where you can read most actual documentation, users comments and changes history.
Here you have wide documentation of match method: http://apidock.com/rails/v3.2.3/ActionDispatch/Routing/Mapper/Base/match
Related
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'
How do I rewrite this old route Rails 1.2.6 to Rails 3? :
# Allow downloading Web Service WSDL as a file with an extension
# instead of a file named 'wsdl'
map.connect ':controller/service.wsdl', :action => 'wsdl'
I canĀ“t see how I should use match route etc.
I have used:
match ':controller/service.wsdl', :action => 'wsdl'
But I dont think it is working correct
Try this:
match '/controller/service.wsdl' => 'controller#service.wsdl', :as => :wsdl
I'm guessing that your controller is not named controller. If it is, I'd rename it and change the above route as well.
I haven't found a good solution to converting Rails 2 parameterized :controller and :action generic routes to the more explicit Rails 3+ format. What I've had to do is go through every permutation in my app and add an explicit route for everything I needed to support. For example, in your case, if you had 3 controllers that supported the wsdl action, I'd add a new route for each using either match or get.
Here's what it might look like, assuming you had a foo_controller, bar_controller, and a blah_controller that all support the wsdl action:
get '/foo/service.wsdl' :to => 'foo#wsdl'
get '/bar/service.wsdl' :to => 'bar#wsdl'
get '/blah/service.wsdl' :to => 'blah#wsdl'
This gets even more fun when you need to support every action on a controller when they use :action.
If anyone has a better method, I'm open (and eager) to hear of a better way.
I am reading Obie Fernandez' "The Rails 3 Way", and there is a bit of it that I am not sure I understand correctly. I am new to rails, and want to make sure I understand it correctly. I have some experience with vanilla Ruby. Not much, but some.
The text in question is as follows: (regarding routing and the config/routes.rb file)
"...
By creating a route like
match 'auctions/:id' => "auction#show", :as => 'auction'
you gain the ability to use nice helper methods in situations like
link_to item.description, auction_path(item.auction)
..."
My question is, specifically what part of match 'auctions/:id' => "auction#show", :as => 'auction' creates the helper functions? (such as link_to auction and auction_path() ) Is it the :as => 'auction' part? Would any helpers be created without appending :as => 'auction'?
My confusion stems from other guides I have seen where this is omitted, and yet helpers seem to be created regardless. What specifically does rails use in match statements in the routes.rb file to create helpers? If it isn't the :as => 'auction' part, then what is the specific purpose of appending this to the match statement?
I know this seems like a super basic question, but this detail seems to get glossed over in the texts I have read thus far. Thanks in advance for any light you can shed on this.
I just tried this:
match "alfa/beta", to: 'users#new'
In this case, even without an :as => 'named_route', I got for free the following helper
alfa_beta_path
which, as expected, points to users#new.
So, it seems that helpers are also automagically generated by parsing the route's string, in case there is no :as specification.
Yes, it is the :as => 'named_route' part that creates the named route (which in turn creates the helpers). As for leaving it off, are you referring to instances of resources :something in routes.rb? The resources method generates a set of URL helpers based on the name of the resource automagically.
I am new to ruby and while creating a sample application found out an issue that whenever I go to http://127.0.0.1:3000/people/index by default show action is executed and index is taken as a parameter. This is server log:
Started GET "/people/index" for
127.0.0.1 at 2010-12-23 18:43:01 +0500 Processing by PeopleController#show as
HTML Parameters: {"id"=>"index"}
I have this in my route file:
root :to => "people#index"
resources :people
match ':controller(/:action(/:id(.:format)))'
What is going on here and how can I fix the issue?
The route
resources :people
creates "sub"-routes
get '/people' => 'people#index'
get '/people/new' => 'people#new'
post '/people' => 'people#create'
get '/people/:id' => 'people#show'
get '/people/:id/edit' => 'people#edit'
put '/people/:id' => 'people#update'
delete '/people/:id' => 'people#destroy'
Actually, all of these sub-routes include (.:format) at the end of the recognized path.
The path /people/index would be recognized by the route /people/:id, mapping to the action #show.
The path /people would be recognized by the route /people, mapping to the action #index.
Use the URL helpers people_path and people_url for the /people route.
To get Rails to travel backward in time to before it espoused REST and to understand /people/index, do this:
resources :people do
get :index => 'people#index'
end
You might want to watch this Railscast episode.
A couple things to keep in mind when working with your routes:
rake routes dumps the map of URLs to your controllers
When providing backwards compatibility, redirect the user to the correct path
I personally have yet to upgrade my app to Rails 3, and I'll be dragging my feet until I really need to do it (just got it out the door not too long ago). In Rails 2.x you had resource routes, but if you kept the default controller/action/id route it would fall through and resolve. It appears that is no longer the case in Rails 3. Essentially your resource routes handle all URLs in that resource namespace (/people in your case).
To provide backwards compatibility, I would add a redirect route to resolve that incompatibility.
match "/people/index", :to => redirect("/people")
The main reason for that is to prevent users from saving an incorrect URL for their personal links--while allowing legacy users to still be able to get where they meant to go.
Edit: New answer, removed pointing out the typo in the question.
I'm getting this error:
uninitialized constant OpenidsController
I can't figure out why. I'm following this guide: http://www.danwebb.net/2007/2/27/the-no-shit-guide-to-supporting-openid-in-your-applications
I used the following command to generate the controller:
script/generate controller Openid new create complete
And I have put the following line in my routes file as the guide says to do:
map.resource :openid, :member => { :complete => :get }
Any ideas? I'm new to RoR so hopefully this is easy for someone else.
You can either change your route to this
map.resource :openid, :member => { :complete => :get }, :controller => 'openid'
or rename your controller class to OpenidsController.
One thing to take note of is that blog post is nearly 3 years old - you might want to consider other articles as well.
You might find this OpenID example helpful, though it's also a little dated at this point.