views:

68

answers:

1

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.

+1  A: 

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.

  1. 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.
  2. 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.

Tony Fontenot