title: Rails 3: making a catch-all route easier to read and amend
body: <p>I'm trying to write a catch-all route in Rails 3, but I want to reserve some terms in it.  I'm specifically following the example put forth in this post, in the answer by David Burrows: <a href="https://stackoverflow.com/questions/4195880/dynamic-routes-with-rails-3">Dynamic routes with Rails 3</a></p>
  
  <p>The syntax I am using is the following:</p>
  
  <pre><code>match '*path' =&gt; 'router#routing', :constraints =&gt; lambda{|req|  (req.env["REQUEST_PATH"] =~ /(users|my-stuff)/).nil? }
  </code></pre>
  
  <p>Now, that syntax works just fine - if a user visits a page with "user" or "my-stuff" in the path, it falls through the catch-all and goes to a specific place.  If the user goes to any other URL, it goes to my routing logic.</p>
  
  <p>My question is more about readability - is there a way I can match the route against something <em>other</em> than a regex?  Is there a way to provide an array of terms to match against?  Also, is there a way to match specific segments of the route, as opposed to the entire thing?</p>
  
  <p>Obviously Rails has built-in routing, but this project has a requirement that for certain routes, the controller not be present in the URL.  Hence, the catch-all.</p>
  
  <p>Thanks for any help</p>
  
  <p>Here's the updated routes file per the answer below:</p>
  
  <pre><code>class RouteConstraint
    RESERVED_ROUTES = ['users', 'my-stuff']
  
    def matches?(request)
      !RESERVED_ROUTES.map {|r| request.path.include?(r)}.empty?
    end
  end
  
  App::Application.routes.draw do
    resources :categories
    resources :sites
  
    match '*path' =&gt; 'router#routing', :constraints =&gt; RouteConstraint.new
  
    devise_for :users, :path_names =&gt;{ :sign_in =&gt; 'login', :sign_out =&gt; 'logout', :registration =&gt; 'register' }
    root :to =&gt; "router#routing"
  end
  </code></pre>