Friday, January 18, 2008

Cool Stuff with the Merb Router

Today I found out something I didn't know about the merb router when looking for routing to subdomains.

I've got a route that looks like this:
  r.match(:first_subdomain => ":account_name") do |k|
k.match("/:controller/:action") #any old route match really
end
That will put the value of the first subdomain into params[:account_name]. Hang on though... That doesn't work by default.

How Is It So!!!?!!?

Well it turns out that when you pass a hash to r.match it uses the hash keys as method calls to the request object. It then compares the values returned to the ones you specify.

So you can have heaps of mini matchers in you matcher and all you have to do is specify a method on the request object and then use that method name as a hash key in the match. This is probably a bit dangerous so be careful with it. In this example this does the job at the top of the route file
module Merb
class Request
def first_subdomain
subdomains.first
end
end
end

4 comments:

fred said...

sweet, that is really nice!
i'm loving merb...
so light.

toolmantim said...

Nice little side-effect! That'd be nice to solidify as a "feature" if/when it gets rewritten.

S. Potter said...

Would it be more direct (for this particular example) to do the following:

# override Merb::Request
module Merb
  class Request
    def account_name
      subdomains.first
    end
  end
end

# in application router.rb
r.match('/:controller/:action')

???

Daniel N said...

@s.potter I'm glad you took it one step further. This was only an example of what could be done. Not perhaps the *best* way of doing things

Cheers
Daniel