? in routes.rb with map.with_options ruby - ruby-on-rails

I'm using named routes in my ruby code. I come from the phpworld where you'll pass information using $_GET and $_POST. I was wondering if there's a way to put this into the routes.rb like this:
map.with_options :controller => 'test' do |m|
m.someurl 'someurl?search=someterm', :action => 'index'
end
Currently it's returning can't convert Hash into String. Thanks!
Justin

If you want to just use a Query String, you don't need to tell your route at all. The params object will contain any passed parameters.
map.with_options :controller => 'test' do |m|
m.some_url 'someurl', :action => 'index'
end
Then when you use the helper method:
some_url_path(:search=> "someterm")
Will create the query string value for you.
However, if you want to pass a parameter to a controller, you can bind them in your route:
map.connect ':controller/:action/:id/:search'
In your controller you can then access:
params[:search]
In your case this would up being something like:
map.with_options :controller => 'test' do |m|
m.some_url 'someurl' :action => 'index'
end
The Rails Routing Guide provides an excellent overview on the subject.

Related

Rails routes with clean urls

My problem is i want to remove the querystring part of this URL and make it clean.
http://staging.mysite.com/mycontroller?name=/philippines/about-manila
currently i have MyController.index() and I parse the name parameter in this method.
What i would eventually want is this :
http://staging.mysite.com/mycontroller/philippines/about-manila
the parameter part 'philippines/about-manila' can have arbitrary number of parameters, like
http://staging.mysite.com/mycontroller/philippines/about-manila/people
How can i do this in routes?
It sounds like you want route globbing. If you use:
map.my_route '/mycontroller/*parts',
:controller => :mycontroller,
:action => :index
and then go to the URL http://staging.mysite.com/mycontroller/philippines/about-manila/people, then your mycontroller controller's index action will be called, and params[:parts] will contain the array ["philippines", "about-manila", "people"].
Is it really arbitrary — or just variable?
If it's just variable, you can enclose optional parameters in parentheses:
match '/:city(/:section(/:subsection))', :controller => :mycontroller,
:action => :index
For Rails 2.x:
map.connect '/:city(/:section(/:subsection))', :controller => :mycontroller,
:action => :index
For Rails 2.x you can use
map.my_route '/:my_param', :controller => :mycontroller, :action => :index
Then in your controller you can access
params[:my_param]
If you want links just go with
my_route_path(:my_param => "mytekst")

How to pass a default query param with Rails 2.3.x routing

I'm trying to do something trivial. I have a bunch of URLs that I need to map like the following:
http://example.com/foo
http://example.com/foo/something
Both need to go to the same controller/action. The problem I'm having is when http://example.com/foo is invoked, I need to specify a default query parameter. I thought that's what the :defaults hash does in routes.rb, but unfortunately the following doesn't work:
map.connect 'foo', :controller => 'something', :action => 'anaction',
:defaults => { :myparam => 'foobar' }
This should route http://example.com/foo to the something controller, anaction action, and make params[:myparam] point to the string "foobar".
I'm assuming for the second example http://example.com/foo/something, I'll need an additional route.
What's the best way to tackle this?
I wouldn't complicate things by adding such logic to my routes file, I'd just do it in my action:
params[:my_param] ||= 'foobar'
Untested, but:
map.connect 'foo', :controller => 'something', :action => 'anaction', :myparam => 'foobar'
It looks like the :controller and :action arguments in there are not in any way special, but just end up feeding into params. The 2.3.8 documentation seems to confirm this.
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.

Rails routes matching query parameters

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?

make dynamic routes from content

I am trying to setup dnamic routes in my rails application.
i.e.
I have a acts model that has a name attribute.
name:string.
What I a trying to do is use that name as my url.
in my route if have
map.connect 'blacktie/:id', :controller => 'acts', :action => 'show', :id => 3
That takes me to http://0.0.0.0:3000/blacktie
I know that i can do something along the lines of
def map.controller_actions(controller, actions)
actions.each do |action|
self.send("#{controller}_#{action}", "#{controller}/#{action}", :controller => controller, :action => action)
end
Just not sure if it is even possible.
Add the following to the bottom of your config/routes.rb
map.connect '*url', :controller => 'acts', :action => 'show_page'
Then define the following in app/controllers/acts_controller.rb
def show_page
url = params[:url]
if Array === url
url = url.join('/')
else
url = url.to_s
end
# you now have the path in url
#act = Acts.find_by_name(url)
if #act
render :action => :show
else
redirect_to some_error_page, :status => 404
end
end
A few gotchas with the above approach.
The route is a catch all. You will be trapping everything that doesn't match a route above it. So make sure it's last and make sure you are ready to handle 404s and the like.
The :url param is an array or a string depending on the route coming in. For example /blacktie/night will be an array with a value of ['blacktie', 'night']. That's why I joined them with in the beginning of show_page. So your find_by_name function could be really smart and allow for nested acts and the such.
Hope this helps.
OR...
Add this to routes (at the bottom):
map.connect ':name', :controller => "acts", :action => "show_page",
:requirements => {:name => /[\w|-]*/}
This tells rails to send anything matching the requirements to your handler. So your show_page would be like the following:
def show_page
#act = Acts.find_by_name(params[:name])
if #act
render :action => :show
else
redirect_to some_error_page, :status => 404
end
end
This gets rid of the some of the gotchas but gives you less options for nesting and the like.

routes.rb explicitly choose template

I would like to create one .erb file to be the output for a number of tiny actions that are just returning JSON. So with routes similar to:
map.json 'contacts_json', :controller => 'contacts', :action => 'get_json'
map.json 'cal_json', :controller => 'calendar', :action => 'get_json'
...
but this requires I create a contacts erb, and a calendar erb so on and so forth. Is there a way to explicitly tell them to use a json erb? Something like:
map.json 'contacts_json', :controller => 'contacts', :action => 'get_json', :view => 'layouts/json.html.erb'
I'm not sure it answers your question but using render :text => #foobar.to_json does wonders in some cases.
No -- you specify what view template to render in the controller action.

Resources