Dogweather
Dogweather

Reputation: 16779

Rails dynamic subpath route?

This seems like it should be easy to do, but I'm not sure how offhand.

I have State and Statute models, and currently use paths like these:

/california/statutes/robbery
/newyork/statutes/burglary

using this route:

match '/:state_id/statutes/:id' => 'statutes#show', :as => :state_statute, :id => /[^\/]+/

But the thing is, in California, statutes are called codes. And in NY, they're laws.

My question is, how could I automatically support these more meaningful paths:

/california/codes/robbery
/newyork/laws/burglary

I have this information stored in the model, which can be used; Statute.meta_name.

Upvotes: 0

Views: 730

Answers (1)

zsquare
zsquare

Reputation: 10146

This should work:

match '/:state_id/:law/:id' => 'statutes#show', :as => :state_statute, :id => /[^\/]+/, :law => Regexp.new(Statute.meta_name.join("|"))

The problem with this is that both these urls would work:

/california/laws/robbery
/newyork/laws/burglary

Which is generally bad for SEO. You could fix that by adding a before filter like:

before_filter :validate_law_title

def validate_law_title
    unless <condition to check if the title used is correct, ie, codes for cali, laws for NY>
        redirect_to <correctly generated url>, :status=>:moved_permanently
    end
end

-- Edit --

To make the generation of routes easier, use a route like:

match '/:state_id/:law/:id' => 'statutes#show', :as => "_state_statute", :id => /[^\/]+/, :law => Regexp.new(Statute.meta_name.join("|"))

And in application_controller, or preferably a lib file, you could add:

# law is the law/rule, etc object
def state_statute_path(law, options={})
    options.merge!(:law => <figure out the label to use from the law object>)
    _state_statute_path(options)
end

Upvotes: 1

Related Questions