I am new to Rails. I found it very strange when I use the resources in routes.rb, after I redirect the page to controller/index, it render the controller/show .
I know GET controller/action is same as match "controller/action", :to => "controller/action"
I think the strange thing happens to me about the redirect, is similar to the GET and Match.
so I wonder what exactly the resources mean, can I use some simple match do the same thing?
resources is a shortcut for generating seven routes needed for a REST interface.
resources :widgets is equivalent to writing
get "widgets" => "widgets#index", :as => 'widgets'
get "widgets/:id" => "widgets#show", :as => 'widget'
get "widgets/new" => "widgets#new", :as => 'new_widget'
post "widgets" => "widgets#create", :as => 'widgets'
get "widgets/:id/edit" => "widgets#edit", :as => 'edit_widget'
patch "widgets/:id" => "widgets#update", :as => 'widget'
put "widgets/:id" => "widgets#update", :as => 'widget'
delete "widgets/:id" => "widgets#destroy", :as => 'widget'
it just saves you the trouble.
By the way, get is not exactly the same as match. get, post, put and delete are shortcuts for limiting the route to a single HTTP verb. The two route definitions below are equivalent.
match 'foo' => 'controller#action', :method => :get
get 'foo' => 'controller#action'
Related
Currently I have these routes in my routes.rb file:
get 'exit' => 'sessions#destroy', :as => 'logout'
get 'enter' => 'sessions#new', :as => '
get 'register' => 'users#new', :as => '
get 'posts' => 'posts#new', :as => '
get 'offers' => 'offers#index', :as => 'offers'
Since Forem (https://github.com/radar/forem) is asking me: # We ask that you don't use the :as option here, as Forem relies on it being the default of 'forem'.
What is the best way to refactor my routes, so they would match Forem requests, to avoid using :as?
Maybe this helps: match 'name_you_want' => redirect('ControllerName#action_name')
I feel like I should know this and I'm certain this could be done more cleanly, but I'm not quite sure the best way to go about it.
How could a set of routes like this be written in a more DRY way?
# Artists
match "/:id/remixes", :to => "artists#remixes", :as => "artist_remixes"
match "/:id/originals", :to => "artists#originals", :as => "artist_originals"
match "/:id/popular", :to => "artists#popular", :as => "artist_popular"
match "/:id/mashups", :to => "artists#mashups", :as => "artist_mashups"
match "/:id/covers", :to => "artists#covers", :as => "artist_covers"
match "/:id/productions", :to => "artists#productions", :as => "artist_productions"
match "/:id/features", :to => "artists#features", :as => "artist_features"
That should do it:
resources :artists, path: '/' do
member do
get 'remixes'
get 'originals'
get 'popular'
get 'mashups'
get 'covers'
get 'features'
end
end
I would look to try and do 1 route and pass list_type as a parameter.
Something like
resources: artists do
resources list_types
end
I would try and avoid having seperate actions for a bunch of methods that probably do similar things.
Ah, should have just thought this through (hungover today):
[:remixes_of, :remixes_by, :originals, :popular, :mashups, :covers, :productions, :features].each do |role|
match ":id/#{role}", to: "artists\##{role}", as: "artist_#{role}"
end
I have some routes looking like this :
match 'hotels/:action(/:id)', :controller => 'hotel', :action => /[a-z]+/i, :id => /[0-9]+/i
And i want to use something like hotels_dislike_path somewhere in my code which refers to /hotels/dislike
How can i do that?
From the routing guide:
3.6 Naming Routes
You can specify a name for any route using the :as option.
match 'exit' => 'sessions#destroy', :as => :logout
So, in your case, that would be:
match 'hotels/:action(/:id)', :controller => 'hotel', :action => /[a-z]+/i, :id => /[0-9]+/i
match 'hotels/dislike(/:id)', :controller => 'hotel', :id => /[0-9]+/i, :as => :hotels_dislike
match 'hotels/like(/:id)', :controller => 'hotel', :id => /[0-9]+/i, :as => :hotels_like
I don't think there's a way to do this dynamically (so you have to define one route for each action, basically). However, you can just define a couple of routes (like above) for the most used actions, and just use hotels_path :action => :really_like for more uncommon actions.
A lot has changed in the world of Rails since 2011 - this is how you would accomplish the same goal in Rails 4.
resources :hotels do
member do
post 'dislike'
post 'like'
end
end
The resulting routes:
dislike_hotel POST /hotels/:id/dislike(.:format) hotels#dislike
like_hotel POST /hotels/:id/like(.:format) hotels#like
hotels GET /hotels(.:format) hotels#index
POST /hotels(.:format) hotels#create
new_hotel GET /hotels/new(.:format) hotels#new
edit_hotel GET /hotels/:id/edit(.:format) hotels#edit
hotel GET /hotels/:id(.:format) hotels#show
PATCH /hotels/:id(.:format) hotels#update
PUT /hotels/:id(.:format) hotels#update
DELETE /hotels/:id(.:format) hotels#destro
Notice thats rails prefixes instead of postfixes the action - dislike_hotel_path not hotels_dislike.
Using Rails 3.1 (not sure if this is applicable to 3.0, etc.)
In routes.rb what's the difference between:
match "team" => "users#index"
and
match "team" => "users#index", :as => :team
I ask because docs say:
3.6 Naming Routes
You can specify a name for any route using the :as option.
match 'exit' => 'sessions#destroy', :as => :logout
This will create logout_path and logout_url as named helpers in your application. Calling logout_path will return /exit
But, in first example above I have access to team_path & team_url in my views?!? So what's the :as => :team do exactly? I must be overlooking something as I've seen example code written like:
match "logout" => "sessions#destroy", :as => :logout
match "login" => "sessions#new", :as => :login
match "signup" => "users#new", :as => :signup
though from my limited testing the :as => :something seems redundant?!?
It seems redundant but it's not... when the name of your route differ from the name you want to give.
The ActionDispatcher does a lot of things by default. You should try to trigger rake routes in your console to test this behavior.
Another example is the shortcut:
match "account/profile"
# same as
match "account/profile", :to => "account#profile"
which will create the named route: account_profile
I already have a route to match /username for the users show page. However, when I add another action, for example: followers and following as below:
resources :users, :only => [:show] do
get :following, :followers
end
I get the URL /users/username/following instead of /username/following.
How can I make all the /users/username URL's be matched as /username/etc.. ?
Here's my /username route:
match '/:id' => 'users#show', :constraints => { :id => /[a-zA-Z0-9\-_]*/ }, :as => "user_profile"
thank you.
Edit:
I have fixed this by adding
match '/:id/following' => 'users#show/following', :as => "user_following"
match '/:id/followed' => 'users#show/following', :as => "user_followers"
But I'm not sure if that's the best solution. What I'd really want is a default route that would match all /:id/:action to the appropriate action omitting the /users.
I have fixed this by adding
match '/:id/following' => 'users#show/following', :as => "user_following"
match '/:id/followed' => 'users#show/following', :as => "user_followers"
But I'm not sure if that's the best solution. What I'd really want is a default route that would match all /:id/:action to the appropriate action omitting the /users.
Near the bottom
match ':id/:action', :controller => :users