Complex routing in rails

Routing in Rails is an implementation of rewriting that maps controllers to addresses besides the active record default. Basically, it allows you to have any URL point anywhere inside your application. While working on Koji, the production pipeline, I began to hit a wall trying to make a directory structured style URL. Something like this:

http://koji.prodpipe.com/projects/the_sandbox/OPN/101/

That would be Shot 101 in the OPN sequence in the project The Sandbox. Seemingly easy enough, but not understanding the way the methods worked was driving me crazy. So here’s a quick rundown of how it works. I wrote this before Rails went 1.1 final, so there might be more effective ways to do this that I haven’t refactored for yet.

You create a route (named or not, i happened to name this one):

<pre>

  1. in config/routes.rb

map.shot_pg ‘projects/:shortname/:acronym/:number’,

So, that takes three symbols, :shortname (which belongs to the project model), :acronym (which belongs to the sequence model), and :number (which belongs to the shot model). The relationship is already established, with project having many sequences, and sequences having many shots. These are defined in the models directory:

<pre>

  1. project.rb
    has_many :sequences
  1. sequence.rb
    belongs_to :project
    has_many :shots

#shot.rb
belongs_to :sequence

There are only a few lines to add to the method in the controller, the first two defining the project and sequence calls that happen and the @shot variable including the parent and child elements that are referenced in the views.

<pre> def show_by_number @project = Project.find_by_shortname(params[:shortname]) @sequence = Sequence.find_by_acronym(params[:acronym]) @shot = Shot.find_by_number(params[:number], rescue logger.error("Couldn't find Shot number #{params[:number]}") flash[:notice] = '<div id="flash" class="bad">That shot does not exist</div>' redirect_to(:action => 'list') end </pre>

Now, when you type in that URL above, you end up at the page.

Sexy!

Post a comment

Name or OpenID (required)


(lesstile enabled - surround code blocks with ---)