I have a very simple question.
Trying to figure out what is the simplest way to route the custom action in rails 3.
Let's say i have controller UsersController and action promote_to_premium
Nor
http://localhost:3000/users/#{user_id}/promote_to_premium
neither
http://localhost:3000/users/promote_to_premium/#{user_id}
works.
Should I specify in routes.rb every custom action that differs from new/delete/update/create/ect/....?????
Thank You.
Yes you need to specify in your routes.rb.
Example:
resources :users do
member do
post :promote_to_premium
end
end
This way you can access the route like this:
http://localhost:3000/users/#{user_id}/promote_to_premium
You should use this in routes.rb:
match "/users/:id/promote_to_premium" => "users#promote_to_premium"
You should mention the route in routes.rb file for custom methods in the controller.
You can specify the routes using either get"" or a match""=>"" or a "post"
when you write get "controller/something" something should be an action(method) called by the name "something" in your controller. But in your case you cannot use get"controller/:id" as there is no ":id" method in your controller. So, you should match your controller/:id to some 'action' in your controller.
Hence you need to write
"match users/:id/promote_to_premium"=> "users#promote_to_premium"
But if you are writing something into the database then you should use 'post'. From whatever i know, i think you can try
match 'users/:id/promote_to_premium' => 'users#promote_to_premium', :via => :post
You can study more about routes in the below link:
http://guides.rubyonrails.org/routing.html
Yes you need to specify every route. Actually you define the normal routes too with the resource command.
There is a specific wildcard command to allow access of any action, but it is only for debug purposes, because it allows access to actions you may not want to be accessible:
match ':controller(/:action(/:id(.:format)))'
Related
I'm working with Rails 3.2 in a project, and I need to create a route for all controllers.
For now, the route is:
resources :people do
collection do
get 'search_for'
end
end
I need thsi "search_for" action for all controllers in application.
Thanks.
you can use this route
match "/:controller/search_for" => redirect("/%{controller}/search_for")
UPDATE: the route above will not work and will cause a redirect loop error simply because it causes a 301 redirect to the same route. solution is to just use
match "/:controller/search_for"
be sure to place this route above all routes so routes that go to the show action will not override this route like.
Simply put this above all routes as:
get ':controller/search_for'
I'm looking to "automatically" generate routes based on actions defined in a controller. resources routing (as far as I know) only automatically generates routes & helpers for http verbs. In this instance I'm serving mostly static pages using rails and have no need for http verbs in my controller.
Specifically:
In a controller I have defined actions which refer to those mostly static pages.
def action
end
In the routes file I have a bunch of
match "/url" => 'controller#action'
I'd like all those matched routes to be generated automatically based on the actions in the controller. Something CONCEPTUALLY along the lines of:
for actions in controller.erb do |action|
'match "/action" => "controller#action"
end
Is this possible? Would I write the code in the routes file directly?
I also have some nested actions to consider... a controller action may be:
def action
def nested_action
end
end
I'd appreciate any thoughts on this matter. Thanks.
What's wrong with the normal /:controller/:action idea?
That won't deal with nested actions, but... I'm having a difficult time understanding why you'd ever want that.
You can do something like this:
controller :controller_name do
get "path/action" => :method_name, :as => :path_action
post "path/save" => :method_name, :as => :path_save
end
That is, you can group different routes within a controller using the method above.
I want the following urls for my UserController:
localhost/user/join
localhost/user/login
localhost/user/user_name (this can be any name in here, it should fire the 'profile' action)
Then within the /user/user_name_here/ folder I want:
/user/user_name/blah1/
/user/user_name/blah2/
/user/user_name/blah3/
It seems doing resources :user only creates things for index/show/get, so I'm confused as to how to do this other than creating so many match '/user/join' etc. lines in routes.
match "user/:user_name" => "users#show"
then /user/username will redirect to the User controller, call the show method, and pass the :user_name param
you could do the same to other actions that doesn't neet parameters,
match '/user/login' => "sessions#new"
match '/user/join' => "user#new"
Yup - 'resources :user' is just scaffolding for the usual CRUD methods. If you want paths additional to those, you're going to have to create routes (it's the only way your app knows how to route a given URL to a given controller and method).
The friendly_id gem does something similar to what you're suggesting (though I believe it's monkey-patching the .find method on ActiveRecords classes rather than handling routing specifically).
I've recently joined the world of Rails app development (Rails3) and I may be abusing resourceful routing.
The default resourceful routing makes some really convenient helper methods for the URLs which I use constantly. My problem is that I have controllers that I specified the routing as resourceful simply to take advantage of those helper methods. I have some basic site navigation that has no business with resources.
resource :home do
member do
get 'main'
get 'about'
get 'login'
get 'help'
end
end
Is there a better way to do what I've been doing? Anything that doesn't require that I manually add routing entries each time I have a new controller action?
Just to clarify, I want to specify routing for a controller without having to explicitly add any new actions but I also want it to auto-generate helper methods. So far, I have to explicitly add routes for each action I want that for. I can get something similar by doing this (in a non-resourceful way),
match 'home/about' => 'home#about'
But I don't want to have to write that very every route that doesn't fall into the convention.
Here's another simpler one. Just add a generic route to the bottom of your routes.rb
match ":controller/:action"
and it will map directly to the specified action of the specified controller. You can be a bit more specific if you like. For example, using get instead of match to restrict to HTTP GET requests, specifying the applicaple controllers etc.
get ":controller/:action", :constraints => { :controller => /home|help/ }
You can look into your controller for public instance methods and generate routes automatically.
# routes.rb
HomeController.public_instance_methods(false).select{|m| !(m.to_s =~ /^_/)}.each do |m|
match "home/#{m}", :action => m, :controller => HomeController, :as => "home_#{m}"
end
This will take the explicit(non-inherited) public instance methods from your controller, and select the ones that don't begin with an underscore(because underscored ones are generated methods for filters, the rest are actual actions). Then it will generate a named route for each.
Keep in mind that routes.rb is processed only at server startup so you will have to restart the server after you add new actions.
I am not sure what I am doing wrong but when I manually add the view "blah.html.erb" to my project and then visit myproject/dog/blah. It says the following:
Routing Error
No route matches "/dog/blah"
There is an action defined in DogController called "blah" which is the following:
def blah
end
NOTE: I add the view using TextMate. I add a new blank file. I think there is some wrong encoding attached to the .html.erb file.
For clarity, you need to either have each action listed explicitly in your routes.rb file; or you need a wildcard pattern to match the controller and action.
What's in your routes.rb file?
Better yet, you need to have something like this
match "/dog/blah", :to => "dog#blah", :as => :dog_blah
This tells your rails app that the url /dog/blah maps to the blah action in your DogController, and the :as option will give you a named route that you can use in your view in this case dog_blah_path.