If I have a Users model, and then an individual user, say, person1, is there a way to have the url: www.myapp.com/person1 show what www.myapp.com/users/person1 would? What would that be called?
Thank you!
You should define a route in your routes.rb file:
match "/:user" => "users#show"
and you'll get the username given in params[:user]. But you need to know that this kind of route could override other routes defined, because it will match any string, so you should at least define some constraints on the username.
For example if your usernames matches a regexp you could define it as a constraint
match "/:user" => "users#show", :constraints => { :user => /some-regexp/ }
and don't forget to set this route as the last one in your routes file, otherwise it will clash for sure with other routes.
Read this for full reference
add "two" routes for the same thing to your app.
# Shorter url to show store items by tags
map.connect '/s/tags',
:controller => 'music',
:action => 'show_by_tags'
map.connect '/music/s/tags',
:controller => 'music',
:action => 'show_by_tags'
Related
I have a URL I want to be able to redirect to.
Something similar to:
"http://localhost:3000/username/admin/page".
I have a match in routes.rb as:
match ':account/admin/:page' => "admin#index"
I have redirect code:
redirect_to :controller => account.username, :action=>"admin", :page=>"index"
This, however comes up with a routing error:
No route matches {:action=>"admin", :controller=>"sdunn", :page=>"index"}
I know what I have done is wrong, but how can I fix this?
Many thanks.
Route is expecting 2 parameters, first one is :account, second is :page, i think you are only passing :page. I would add :as => 'some_name' to your route and then use _path :
routes.rb
match ':account/admin/:page' => "admin#index", :as => 'my_route'
controller:
redirect_to my_route_path(#user, #page)
my_route_path could be something different depending on your exact route file, so use
rake routes | grep my_route
to see exact name, then add _path to the end.
I am working on Rails 2.3.11. If I have a url like http://www.abc.com/users/e.f.json , I expect the id to be 'e.f' and the expected format to be 'json'. Can someone please suggest a way to do it.
Thank you!
Because of the :format convention, Rails will parse all parameters without any dots. You can have route parameters with dots if you want:
# You can change the regex to more restrictive patterns
map.connect 'users/:id', :controller => 'users', :action => 'show', :id => /.*/
But since both '*' and '+' regex wildcards are greedy, it will ignore the (.:format) param completely.
Now, if you absolutely need to have dots in the username, there is a pseudo-workaround that could help you:
map.connect 'users/:id:format', :controller => 'users', :action => 'show', :requirements => { :format => /\.[^.]+/, :id => /.*/ }
map.connect 'users/:id', :controller => 'users', :action => 'show'
The downside is that you have to include the dot in the :format regex, otherwise it would be caught by the username expression. Then you have to handle the dotted format (e.g.: .json) in your controller.
Here is a solution similar to andersonvom's, but keeps it all in one rule (and uses some modern Rails routing abbreviations).
map.connect 'users/:id(.:format)', to: 'users#show', id: /.*?/, format: /[^.]+/
(Note the . in front of :format)
The trick is to add an optional format, (.:format) and make the id regex non-greedy so the format is recognised. Keeping it in one rule is important if you want to give the route a name, so that you can use it for redirects, links, etc in a format-agnostic way.
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.
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?