Rails 3 Routing - ruby-on-rails

I have a community_users model that I route in the following way:
resources :communities do
resources :users
end
This creates the route /communities/:id/users/.
I'd like to configure this route so that only the name of the community with the corresponding :id is shown.
In other words, if a community has an id of '1' and the name 'rails-lovers' - the route would read:
/rails-lovers
and not:
/communities/1/users/

You might want to check out the gem friendly_id
That will give you the clean URLs you are looking for.

I'm not quite sure if this is what you're looking for, but:
One option would be to create the route
match ':community_name' => 'users#show_users_for_community'
and then in the UsersController have
def show_users_for_community
#community = Community.find_by_name(params[:community_name])
<do what you need to do here>
end
I'm not sure if that route will match too many URLs or not -- it's a very general route. So if you do this, maybe put it low down in your routes file.

Related

Rails resources route with dynamic prefix instead of controller name

I have a TextsController, each Text can be of a different (fixed) type.
Let's say I have a "book" type. I want to create a resource route to show a text, and I want the route to look like this:
/book/my-book
Another type, "manual" for instance, should lead to using the following URL:
/manual/rtfm
Well, I have RTFM and I can't get it to work the way I thought it should work.
Here's what I've tried:
scope '/:text_type' do
resources :texts, only: :show
end
rake routes shows me the following route spec:
text GET /:text_type/texts/:id(.:format) texts#show
I don't get why the static 'texts' segment should be there?
So I tried including an empty path option:
scope '/:text_type', path: '' do
resources :texts, only: :show
end
Which doesn't change anything, I guess because (from source) my first argument to scope actually overrides any value given to path.
The only route setup that got me what I'm looking for is this:
scope '/:text_type' do
resources :texts, only: :show, path: ''
end
It seems to completely defeat the purpose of scope which is to "[scope] a set of routes to the given default options".
Why wouldn't any of the previous forms actually override path for my resources call?
Looks like a bug to me?
So should I file a bug report, or will you hit me hard on the head with the f* manual? ^^
First of all the scoping thing. Routes with scope are for namespacing routes, as you would do for admin areas. So the mentioned routes are generated correctly and there is no bug (and no bug report needed). You can read more details about namespacing at Controller Namespaces and Routing.
You could slug the parameters yourself by following 'Creating Vanity URLs in Rails'
or use the friendly_id gem like the Railscast advises.
Though I would stick to ids as long as I could for several reasons.

change routing name dynamically

I have to modify the routes file in order to have SEO improvement.
This is my context, a rails backend generate a JSON feed with the route's name in, I have to read it and change the default name.
For example, I have this:
get '/people' => 'people#show', as: :people
and I'd like to change /people in some value read from my JSON feed.
I created a class to get the JSON object in my app
class JSONDatabase
def initialize(kind_of_site)
#kind_of_site = kind_of_site
end
def fetch_database_remote(url)
JSON.parse(open(url).read)
end
end
but how can i access it in routes file?
Thank you
You don't necessarily need to modify your application's routes. What you can do is define a wild card route that leads to a unique controller where you read the updated route. This approach is kind of hackish but gives you the unlimited routes you need without modifying the routes.
Your config/routes.rb file would look something like this:
resources :defined_models
root to: 'controller#action'
# At last we define the wildcard route
get '/:route' => 'routing_controller#routing_action'
Then, at this routing action we can do the job of seeing if this route (now defined in the params[:route] variable) corresponds to the modified one. Just remember to redirect to a 404 if the route given is not defined, since with this approach you loose the Rails default way of dealing with undefined routes.

Obtaining ID of containing resource via params[:id] for custom actions

I have the following routes in my config/routes.rb file:
resources :employees do
get 'dashboard'
get 'orientation'
end
employees refers to a regular resource handling the standard RESTful actions. dashboard and orientation are what I currently refer to "custom actions" which act on Employee instances. I apologize if I have my terminology mixed up and dashboard and orientation are really something else. These custom actions respond to URLs as follows:
http://myhost/employees/1/dashboard
i.e. They're "member" actions much like show, edit etc.
Anyway, this all works well enough. Regular actions such as show on EmployeesController obtain the ID of the associated Employee through params[:id]. However, with this current structure, dashboard and orientation have to use params[:employee_id] instead. This is not too difficult to deal with, but does lead to some additional code complexity as my regular before_filters which expect params[:id] don't work for these two actions.
How do I have the routing system populate params[:id] with the ID for these custom actions in the same way as show etc.? I've tried various approaches with member instead of get for these actions but haven't got anything to work the way I would like yet. This app is built using Ruby on Rails 3.2.
This might help you:
resources :employees do
member do
get 'dashboard'
get 'orientation'
end
end
and the above will generate routes like below, and then you will be able to use params[:id] in your EmployeesController.
dashboard_employee GET /employees/:id/dashboard(.:format) employees#dashboard
orientation_employee GET /employees/:id/orientation(.:format) employees#orientation
I haven't tested this example, but you can set the resourceful paths explicitly.
Something like this might work:
resources :employees, path: '/employees/:id' do
get 'dashboard', path: '/dashboard'
get 'orientation', path: '/orientation'
end

What will be my route?

I'm working on Rails 3.
My URL is: http://localhost:3000/terms_and_conditions?val=pp
My method is below:
class GeneralController < ApplicationController
def terms_and_conditions
if !params[:val].nil?
#val=params[:val]
else
#val='tc'
end
end
end
What will be my route? Please help me to create the route.
I suggest you first read the guides titled Rails Routing from the Outside In.
To setup a simple GET accessible route add the following to your routes.rb file
get "/terms_and_conditions" => "general#terms_and_conditions"
If you need more than just GET, you can use match instead. In your app root you can perform rake routes to see all the routes of your app as well. With regards to your choice of exposing /terms_and_conditions — it would be better if you used a shorter path such as /terms and/or consider doing /terms-and-conditions instead.
Try:
[YourAppNameHere]::Application.routes.draw do
match '/terms_and_conditions', to: 'general#terms_and_conditions'
end

Confused about routes setup -- Rails 3.1

I think I'm running across a conflict due to names:
Two models: store coupon
Url needed that will display coupons: http://localhost/coupons/:store_name ('coupons' is written in the url, not replaced with anything)
Controller name: coupons_controller
Here is what I have in my routes right now:
match '/coupons/:store_name' => 'coupons#index', :as => :stores
When I try to do redirect stores_path(store) in another controller, I get this error:
No route matches {:controller=>"coupons"}
Any clues? I'm new to rails so I bet it's a silly mistake.
UPDATE
Is there a central place to tell the dynamic _path() functions to use a specific url structure? i.e. Instead of having to do the following everywhere:
redirect_to stores_path(:store_name => store.store_name)
Instead using just:
redirect_to stores_path(store)
yes you can, redefine to_param in your model:
class Store < ...
def to_param
store_name
end
end
redirect_to stores_path(:store_name => store)
should work if it doesn't (cannot confirm right now), you should be able to do the (little hacky)
redirect_to stores_path+"?store_name=yourstorename"
Doing it the restful way, you should probably have something like this (in your routes):
resources :stores do
resources :coupons # this will give you e.g. /stores/:store_id/coupons for the coupons#index action
end
If you want to use the store name instead of the ID, just search SO for using "slug" or have a look here: getting a 'name' based URL in RESTful routes instead of an id based url or ID + Slug name in URL in Rails (like in StackOverflow)

Resources