Create a rails route with only parameters - ruby-on-rails

I want to create a rails route which has only parametrs. Eg:
match '/:taxonomy/:taxon/(:tag)' => 'shop#index', :as => 'shop'
Currently I am creating a separate rails route for each possible value of taxonomy. E.g.
match '/jewellery/:taxon/(:tag)' => 'shop#index', :as => 'shop'
match '/bags-and-wallets/:taxon/(:tag)' => 'shop#index', :as => 'shop'
match '/mens-jewellery/:taxon/(:tag)' => 'shop#index', :as => 'shop'
match '/mens-accessories/:taxon/(:tag)' => 'shop#index', :as => 'shop'
If I use /:taxonomy/:taxon/(:tag), some other pages also start getting routed to the shop_controller.
Is this possible? Maybe by setting allowed values for the taxonomy parameter?

Just place your only-parameters-matcher after all others.
i.e. make sure that your route with parameters is the last route in your routes file.

Related

Rails: simple routing question about :as => :something

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

How do I 301 redirect these route changes?

I have a couple routes like this:
match ':category/:brand/:permalink' => 'products#show', :as => :public_product
match 'stoves' => 'home#stoves', :as => :stoves
I changed them to this:
match ':category/:brand/:permalink' => 'products#show', :as => :public_product
match 'wood_stoves' => 'home#wood_stoves', :as => :stoves
I changed the category record titled stoves to wood_stoves.
Can I add a route redirect that allows for wildcards that would change anything like domain.com/stoves or domain.com/stoves/morso/8140-contemporary to domain.com/wood_stoves or domain.com/wood_stoves/morso/8140-contemporary, respectively? Or should I put this in my apache virtualhost config block?
Let your route.rb to be like this:
match ':category/:brand/:permalink' => 'products#show', :as => :public_product
match 'stoves' => 'home#stoves', :as => :old_stoves # anything else except stoves
match 'wood_stoves' => 'home#wood_stoves', :as => :stoves
In your Home Controller:
def stove
redirect_to stoves_path(# Use parameters here when a user hits a link like domain.com/stoves or domain.com/stoves/morso/8140-contemporary)
end
def wood_stoves
# your code here..
end
match ':category/:brand/:permalink' => 'products#show', :as => :public_product
match 'stoves' => 'home#stoves', :as => :old_stoves #
match 'wood_stoves' => 'home#stoves', :as => :stoves
This is enough i think.
If you are so particular about to change the name of the action to wood_stoves then i think you need to do Surya's solution

Rails 3: Replace /users/username/something for /username/something

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

(Rails 3) Is it possible to hardcode ids in a named route?

As far as I know, the following is the encouraged way to create a simple named route in Rails 3:
match 'sign-in' => 'sessions#create', :as => :sign_in
Is there a clean way to hardcode an id (or any parameter) in a named route? For a silly example:
match 'first-user' => 'users#show', :as => :first_user, :id => 1
Did you try that? It just works like that.

get, match and resources in routes.rb

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'

Resources