Rails: routing question - ruby-on-rails

I have this in my routes:
resources :cvits
which produces these routes:
cvits GET /cvits(.:format) {:controller=>"cvits", :action=>"index"}
POST /cvits(.:format) {:controller=>"cvits", :action=>"create"}
new_cvit GET /cvits/new(.:format) {:controller=>"cvits", :action=>"new"}
edit_cvit GET /cvits/:id/edit(.:format) {:controller=>"cvits", :action=>"edit"}
cvit GET /cvits/:id(.:format) {:controller=>"cvits", :action=>"show"}
PUT /cvits/:id(.:format) {:controller=>"cvits", :action=>"update"}
DELETE /cvits/:id(.:format) {:controller=>"cvits", :action=>"destroy"}
but I would like my urls to be singular (eg /cvit/, /cvit/new, /cvit/:id). What would be the easiest way to change this??????
Thanks!!!!
SOLVED: Figured it out, I did:
resources :cvits, :path => 'cvit'

Well:
resources :cvit
Check doc here: http://guides.rubyonrails.org/routing.html#singular-resources
Or a better fit:
resources :cvits, :path => "cvit"
Same doc page.

You just want a singular resource:
resouce :cvit
# instead of
resources :cvits
Note that your controller names etc. will still be plural (CvitsController). In order to specify otherwise you can pass:
resource :cvit, :controller => 'cvit'
Also, note that when you do this you have no index action. Singular resources assume there's only one thing there, instead of being many.
Assuming that is what you have (a singular resource), this is better than passing the path option. The path option is just overriding the name and not the behavior (i.e. you still have an index, even though that doesn't make sense if you're dealing with a singular resource).

Related

Rails - start your route from second element of the path

Is there a way in rails to start routing from 2nd part of the url path?
for example localhost:3000/tenant_name/posts for resources:posts
tenant_name is a name of the schema in my database.i want switch to respective tenant using the tenant_name.
when i run this now will get No route matches [GET] "/tenant_name/posts"
I need to visit posts even if replace "tenant_name"with any tenant_name.How to do?
Using scope without any options and only a scope name, it will just change the resources path.
scope :sometext_here do
resources :posts
end
This will generate url like -
Prefix Verb URI Pattern Controller#Action
posts GET /sometext_here/posts(.:format) posts#index
POST /sometext_here/posts(.:format) posts#create
post GET /sometext_here/posts/:id(.:format) posts#show
PATCH /sometext_here/posts/:id(.:format) posts#update
PUT /sometext_here/posts/:id(.:format) posts#update
DELETE /sometext_here/posts/:id(.:format) posts#destroy
Alternative way to use it -
get '/:dynamic_text/posts' => 'posts#index', as: :all_posts
So it can be used as
all_posts_path(dynamic_text: "sometext_here")

Change name of scaffold routes

Is there a way to change the name of the routes that my scaffold created? I made a scaffold for Cars. Currently I have resources :cars in my routes. How can I change the routes such that my url shows http://localhost:3000/transportation instead of http://localhost:3000/cars? I do not need to change the name of the entity in my schema, all I want to change are the routes associated with it. How can I go about this?
Is there no other way to achieve this but to do a get for each? Ex:
get '/transportation', to: 'cars#index', as: 'cars_index'
You can define the new route after the resources created by your scaffold to respond to your cars controller and index action, or any other other, depending on what you want to achieve.
resources :cars
get 'transportation', to: 'cars#index'
If you want to apply it for all your routes on the car scaffold, then you can pass a path option:
resources :cars, path: 'transportations'
This way the routes pointing to car won't be available and will be replaced for transportations.
You can redefine resource routes with custom URLs by passing a string of your choice along with :path option along with its route definition in routes.rb
resources :cars, :path => "transportation"
With this route definition, access to cars resources in your app will be routed to these URLs
cars GET /transportation(.:format) cars#index
POST /transportation(.:format) cars#create
new_car GET /transportation/new(.:format) cars#new
edit_car GET /transportation/:id/edit(.:format) cars#edit
car GET /transportation/:id(.:format) cars#show
PATCH /transportation/:id(.:format) cars#update
PUT /transportation/:id(.:format) cars#update
DELETE /transportation/:id(.:format) cars#destroy

Rails routes config thinks action method is an object id

I'm developing rails application and encountered such problem.
I have movies_controller.rb, where I have these actions and routes defined:
Prefix Verb URI Pattern Controller#Action
movies GET /movies(.:format) movies#index
POST /movies(.:format) movies#create
new_movie GET /movies/new(.:format) movies#new
edit_movie GET /movies/:id/edit(.:format) movies#edit
movie GET /movies/:id(.:format) movies#show
PATCH /movies/:id(.:format) movies#update
PUT /movies/:id(.:format) movies#update
DELETE /movies/:id(.:format) movies#destroy
root GET / redirect(301, /movies)
movies_by_director GET /movies/by_director(.:format) movies#by_director
But when I try to go to /movies/by_director?director="something", rails think, that I'm navigating to movies#show action with parameter :id = by_director.
What am I doing wrong?
Routes are matched in the order they are specified so make sure the route for "by_director" is defined above the resource routes for movies.
Something like this should do the trick:
get '/movies/by_director' => 'movies#by_director'
resources :movies
There are two problems in one here:
The default pattern matching for :id is loose enough that by_director is interpreted as an :id.
Routes are matched in order and GET /movies/:id appears before GET
/movies/by_director.
You can manually define GET /movies/by_director before your resources :movie as infused suggests or you could add a constraint to narrow what :ids look like:
resources :movies, constraints: { id: /\d+/ } do
#...
end
Manually ordering the routes is fine if there's just one or two of them to deal with, constraining :id is (IMO) cleaner and less error prone.

Ruby on Rails 3: Change default controller and parameter order in routing

I have a Rails app that has a controller called domain which has a nested controller called subdomain and stats. I have defined them in routes.rb:
resources :domains do
resources :subdomains, :stats
end
I have changed the to_param of the domain and subdomain models to use the name of the domain, e.g.: the routing I get is http://site/domains/foo/subdomains/bar.
I would like to tidy it up to so that instead of using http://site/domains/foo/subdomains/bar I could access it with just http://site/foo/subdomains/bar. I have tried the following in routes.rb:
match "/:id/" => "domains#show", :as => :domain
Which works fine, but it only gives me the ability to use the path http://site/foo but for example http://site/foo/subdomains/bar doesn't. I could create match lines for every respective model and nested model but that does nothing to other helpers besides domain_url - i.e. edit_domain_url points to /domains/foo/edit/ instead of /foo/edit.
Is there a way to change the routing so that the resources generates helpers that point to the root url without the 'domains' part?
The single match in your routes creates only one route. Resource helpers create many routes at once. Luckily there are a lot of options for customisation. If you want to omit /domains/ from your paths, it's as simple as:
resources :domains, :path => "/" do
resources :subdomains, :stats
end
With the above in config/routes.rb, running rake routes says the following:
domain_subdomains GET /:domain_id/subdomains(.:format)
domain_subdomains POST /:domain_id/subdomains(.:format)
new_domain_subdomain GET /:domain_id/subdomains/new(.:format)
edit_domain_subdomain GET /:domain_id/subdomains/:id/edit(.:format)
domain_subdomain GET /:domain_id/subdomains/:id(.:format)
domain_subdomain PUT /:domain_id/subdomains/:id(.:format)
domain_subdomain DELETE /:domain_id/subdomains/:id(.:format)
domain_stats GET /:domain_id/stats(.:format)
domain_stats POST /:domain_id/stats(.:format)
new_domain_stat GET /:domain_id/stats/new(.:format)
edit_domain_stat GET /:domain_id/stats/:id/edit(.:format)
domain_stat GET /:domain_id/stats/:id(.:format)
domain_stat PUT /:domain_id/stats/:id(.:format)
domain_stat DELETE /:domain_id/stats/:id(.:format)
domains GET /(.:format)
domains POST /(.:format)
new_domain GET /new(.:format)
edit_domain GET /:id/edit(.:format)
domain GET /:id(.:format)
domain PUT /:id(.:format)
domain DELETE /:id(.:format)
Looks like all the routes you need!

How to rename the default identifier param "id" in Rails' map.resources()?

I like all the default routes that are generated by Rail's map.resources. But, there are cases where I would like to use a non-numeric identifier in my routes. For example, If have a nested route consist of users and their articles, a standard route could be written as such:
map.resources :users, :has_many => [:articles] # => e.g. '/users/:id/articles/:id'
However, there are many advantages / reasons not to use the default numerical identifier generated by Rails. Is there a way to replace the default :id params to another canonical identifier of my choice without resulting to writing custom routes for every standard action? Say if I want a route in the following format:
'/users/:login/articles/:id'
Is this kind of routes achievable using map.resources?
As of Rails 2.3, it's not possible to change the parameter name and still use the automatic routing that #resources provides.
As a workaround, you can map articles with a :path_prefix and :name_prefix:
map.resources :articles, :path_prefix => "/users/:login",
:name_prefix => "user_"
The :path_prefix affects the URL, and the :name_prefix affects the generated named routes, so you'll end up with these routes:
user_articles GET /users/:login/articles(.:format) {:controller=>"articles", :action=>"index"}
POST /users/:login/articles(.:format) {:controller=>"articles", :action=>"create"}
new_user_article GET /users/:login/articles/new(.:format) {:controller=>"articles", :action=>"new"}
edit_user_article GET /users/:login/articles/:id/edit(.:format) {:controller=>"articles", :action=>"edit"}
user_article GET /users/:login/articles/:id(.:format) {:controller=>"articles", :action=>"show"}
PUT /users/:login/articles/:id(.:format) {:controller=>"articles", :action=>"update"}
DELETE /users/:login/articles/:id(.:format) {:controller=>"articles", :action=>"destroy"}
As a general rule-of-thumb, though, I'd stick with the Rails default convention of :user_id, with the routing you posted in your question. It's generally understood that :id and :user_id don't necessarily imply "numeric identifier" — they imply "resource identifier," whatever that might be. And by sticking to the default convention, your code will be easier to understand for anyone who's used resource routes in Rails.
To use a non-numeric identifier for a resource, just redefine #to_param in your model. Then, make sure to use a finder in your controller that will find by this identifier (rather than the numeric ID), such as User#find_by_login!.
You can change the default of using the ID in URLs by overriding to_param in your model. e.g.
class User < ActiveRecord::Base
def to_param
login
end
end
user_articles_path(#user) => "/users/:login/articles"
The only other change you'll need to make is to find users by login rather than by ID in your controllers.

Resources