Is there a way to look up the HTML for a given controller action? For example, I would like to be able to associate GET with index and PUT with update. I want to be able to do this dynamically based on the routes.
I can get the action methods for each controller using Controller.action_methods, but this returns a set of strings of action methods. Ideally what I would like is a hash of the form: {:action => :verb}.
Read the rake routes task, that will provide insight:
e.g:
users GET /users(.:format) {:controller=>"users", :action=>"index"}
I assume this is what you are after?
:method is part of a :conditions hash you can pass in to map.connect
map.connect 'post/:id', :controller => 'posts', :action => 'create_comment',
:conditions => { :method => :get }
To provide a useful object with all controllers, actions, and associated verbs
def all_routes
#all_routes ||= Rails.application.routes.routes.map do |route|
{ alias: route.name,
path: route.path.spec.to_s,
controller: route.defaults[:controller],
action: route.defaults[:action],
verb: route.verb.source.to_s.delete('$'+'^')
}
end
end
Related
When I run
rake routes
I see the following:
POST /articles/:article_id/comments(.:format) {:action=>"create", :controller=>"articles/comments"}
This makes perfect sense. It means if I make a post request to a url of the form /articles/1234/comments, it runs the create action of the controller in articles/comments_controller.rb with the id paramater set as 1234.
But then I see this line also:
/article/:id/:action {:root=>"article", :controller=>"article/article", :title=>"Article"}
And I'm not sure what the ":root" means. Can someone please explain?
EDIT:
I'm using Rails 2.3.18.
Here is the relevant line in the routes.rb file
#routes.rb
map.connect '/article/:id/:action', :controller => 'article/article', :root => 'article', :title => 'Article'
Like :title, it's just another key,value that gets merged into the params hash.
From http://rubydoc.info/docs/rails/2.3.8/ActionController/Routing ( Defaults routes and default parameters)
More formally, you can include arbitrary parameters in the route,
thus:
map.connect ':controller/:action/:id', :action => 'show', :page =>
'Dashboard'
This will pass the :page parameter to all incoming
requests that match this route.
It doesn't have any additional meaning in Rails. My guess is that your app is using it for breadcrumbs or something similar.
In the last we generated a useful link for our mail.
generate an real url with rails for an e-mail
This works fine, very fine. But we want to call the shoe-action :-)
<%=link_to('Link', :controller => 'mycontroller', :action => 'show', :id => #mycontroller.id )%>
The url looks so
http://localhost:3000/mycontroller/show/10
we need this structure
http://localhost:3000/mycontroller/10
The rake routes command said this
mycontroller GET /mycontroller/:id(.:format) mycontroller#show
How do we get the needed structure? Do we need to edit our routes, or is there another way to get the right url?
Try to use the route helper
mycontroller_url(#mycontroller.id)
instead the {:controller => ..., :action => ...}
your link_to helper should look like this for better example i use the user show action
rake routes return this
user GET /users/:id(.:format) users#show
and now I know I can use the user_url(#user) helper
<%=link_to('Link', user_url(#user) )%>
I'm trying to route only an http verb. Say I have a comments resource like so:
map.resources :comments
And would like to be able to destroy all comments by sending a DELETE /comments request. I.e. I want to be able to map just the http verb without the "action name" part of the route. Is this possible?
Cheers
You could do this:
map.resources :comments, :only => :destroy
which produces a route like the following (you can verify with rake routes)
DELETE /comments/:id(.:format) {:controller=>"comments", :action=>"destroy"}
But note that the RESTful destroy is designed for removing a specific record not all records so this route is still expecting an :id parameter. A hack might be to pass some sentinel value for :id representing "all" in your application context.
On the other hand, if your comments belong to another model, then removing the other model would/should remove the comments too. This is conventionally how multiple row deletes might normally occur.
Since this is not standard RESTful action, you will need to use a custom route.
map.connect '/comments',
:controller => 'comments',
:action => "destroy_all",
:conditions => { :method => :delete }
In your controller:
class CommentsController < ApplicationController
# your RESTful actions here
def destroy_all
# destroy all your comments here
end
end
In view, invoke like this:
<%= link_to "delete all comments",
comments_path,
:method => :delete,
:confirm => "Are you sure" %>
ps. I didn't test this code, but I think it should work.
Currently we are using method_missing to catch for calls to SEO friendly actions in our controllers rather than creating actions for every conceivable value for a variable. What we want are URLS like this:
/students/BobSmith
and NOT /students/show/342
IS there a cleaner solution than method_missing?
Thank you!
You can define a route for that particular format fairly easily.
map.connect "/students/:name", :controller => :students, :action => :show, :requirements => {:name => /[A-Z][A-Z]+/}
Then in your show action you can find by name using params[:name].
You can create a catch-all route. Put this at the bottom of config/routes.rb with whatever controller and action you want:
map.connect '*path', :controller => '...', :action => '...'
The segments of the route will be available to your controller in the params[:path] array.
Rails routes are great for matching RESTful style '/' separated bits of a URL, but can I match query parameters in a map.connect config. I want different controllers/actions to be invoked depending on the presence of a parameter after the '?'.
I was trying something like this...
map.connect "api/my/path?apple=:applecode", :controller => 'apples_controller', :action => 'my_action'
map.connect "api/my/path?banana=:bananacode", :controller => 'bananas_controller', :action => 'my_action'
For routing purposes I don't care about the value of the parameter, as long as it is available to the controller in the params hash
The following solution is based on the "Advanced Constraints" section of the "Rails Routing from the Outside In" rails guide (http://guides.rubyonrails.org/routing.html).
In your config/routes.rb file, include a recognizer class have a matches? method, e.g.:
class FruitRecognizer
def initialize(fruit_type)
#fruit_type = fruit_type.to_sym
end
def matches?(request)
request.params.has_key?(#fruit_type)
end
end
Then use objects from the class as routing constraints, as in:
map.connect "api/my/path", :contraints => FruitRecognizer.new(:apple), :controller => 'apples_controller', :action => 'my_action'
Unless there is a concrete reason why you can't change this, why not just make it restful?
map.connect "api/my/path/bananas/:id, :controller => "bananas_controller", :action => "my_action"
If you have many parameters, why not use a POST or a PUT so that your parameters don't need to be exposed by the url?