-
Notifications
You must be signed in to change notification settings - Fork 40
The Router
The merb router is found in $MERB_ROOT/config/router.rb. It will by default contain a block that looks like:
Merb::Router.prepare do
# RESTful routes
# resources :posts
# This is the default route for /:controller/:action/:id
# This is fine for most cases. If you're heavily using resource-based
# routes, you may want to comment/remove this line to prevent
# clients from calling your create or destroy actions with a GET
default_routes
# Change this for your home page to be available at /
match('/').to(:controller => 'reports', :action =>'index')
endAs the comments mention, you can add a resource to the router by adding the following code within the Merb::Router.prepare block
resources :cars
Resources use the model's id in the URL by default, but this can be overridden using the identify block or a parameter to the resource definition to make a URL more readable. For instance, the following code uses the model's slug.
identify Car => :slug do
resources :cars
end
# or alternatively:
resources :cars, :identify => :slugYour controller must be changed to find the Car by slug. The show action would look something like that:
def show
@car = Car.first(:slug => params[:slug])
raise NotFound unless @car
display @car
endThe router allows you to nest models. The following code, nests Cars within CarModels, which are in turn nested within Makes.
resources :makes do
resources :car_models do
resources :cars
end
endWith the above code you would then access cars with the URL http://localhost:4000/makes/5/car_models/10/cars/15.
You can now generate URLs for your nested resources using the following format:
url(:make_car_model_cars, @car.car_model.make, @car.car_model)
url(:make_car_model_car, @car.car_model.make, @car.car_model, @car)
url(:edit_make_car_model_car, @car.car_model.make, @car.car_model, @car)Finally, you can combine the identify block for friendly URLs with nest resources. The following code nests Cars within CarModels within Makes, and uses their slugs instead of their ids for access.
identify Make => :make_slug do
resources :makes do
identify CarModel => :model_slug do
resources :car_models do
identify Car => :car_slug do
resources :cars
end
end
end
end
endNOTE: currently the identify attributes are passed in with the name you give them here, so when nesting resources, they must have different identifiers. If you named them all "slug", then you will only get one of them passed into your controller.
Unless your slugs are all globally unique, your controller's show action would look something like:
def show
@car = Make.first(
:make_slug => params[:make_slug]
).car_models.first(
:model_slug => params[:model_slug]
).cars.first(
:car_slug => params[:car_slug]
)
raise NotFound unless @car
display @car
endIf you use action-args to make your controllers more readable, your show action might look more like the following:
def show(make_slug, model_slug, car_slug)
@car = Make.first(
:make_slug => make_slug
).car_models.first(
:model_slug => model_slug
).cars.first(
:car_slug => car_slug
)
raise NotFound unless @car
display @car
end