Skip to content

Instantly share code, notes, and snippets.

@mjy
Created October 27, 2011 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjy/1319716 to your computer and use it in GitHub Desktop.
Save mjy/1319716 to your computer and use it in GitHub Desktop.
:constraint Route matching
The problem is pretty straightforward, for a rails 3.0.10 app (upgrading form 2.3.10, which uses match style routes), ruby, 1.9.2.
I have basic routes:
/projects/1/foo/bar/1.json # controller => foo, :action => bar, etc...
/projects/1/public/foo/bar/1.json # controller => public/foo, :action => bar, etc..
I need to match the "public/foo" controller first, if no public provided just match "foo" as the controller. The format needs to be optional.
My routes.rb:
match "/projects/:proj_id/:controller(/:action(/:id(.:format)))"
match "/:controller(/:action(/:id(.:format)))"
The main reason I'm using match is I have *many* other non-restful actions for the resources in *many* controllers (e.g. customized lists/customized search forms,"complex" navigation, AJAX calls etc.). Yes these could be reformulated (and will in time) but at present it's just not feasible for the app to not have a :action based matching.
My ideal situation: I use resources, but I can add a one-off setting that grabs all non-restful actions and routes them as necessary (as in the match solution above).
My unit tests (these really only cover resourceful methods so they don't quite cover my full list of needs):
def test_recognizes_basic_private_pattern
assert_recognizes({"controller" => "otu", "action" => "new", "proj_id" => "1"}, "/projects/1/otu/new")
end
def test_recognizes_basic_private_pattern_with_id
assert_recognizes({"controller" => "otu", "action" => "show", "proj_id" => "1", "id" => "1"}, "/projects/1/otu/show/1")
end
def test_recognizes_basic_public_pattern
assert_recognizes({"controller" => "public/otu", "action" => "show", "proj_id" => "1", :id => "1"}, "/projects/1/public/otu/show/1")
assert_recognizes({"controller" => "public/otu", "action" => 'index', "proj_id" => "1"}, "/projects/1/public/otu")
end
Currently last test fails with "No route matches "/projects/1/public/otu/show/1"".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment