How to merge routing constraints based on objects?

Hi,

I’ve got routes similar to this:

scope :constraints => Subdomain.new do

root :to => “something#index”, :constraints => Authenticated.new(true)

root :to => “other#index”

end

The problem is that the constraint in the inner route seems to overwrite the constraint defined for the scope. Is there some way to merge them? For now I’ve created a wrapper class for constraints where I can pass a list of constraints and it just checks if every constraint.matches? returns true, but I have to repeat all the constraints defined previously:

scope :constraints => Subdomain.new do

root :to => “something#index”, :constraints => Wrapper.new([Subdomain.new, Authenticated.new(true)])

root :to => “other#index”

end

and that sucks. Is there a way to somehow merge such constraints instead of repeating them like that?

Could you have your Authenticated constrain inherit from the Subdomain constraint and implement its matches? method as well?

Something like this maybe? Don’t have too much experience with constraints so I’m not sure of the exact syntax, but might be worth playing around.

class Authenticated < Subdomain

def matches?(request)

return false unless super(request) # check Subdomain constraint

# other code here for authenticated constraint

end

end

Thanks, but it doesn’t really solve the problem with having to repeat constraints from the outer scope. Additionally, in my case the “Authenticated” constraint is used in few other places as well, so I’d have to name this particular one e.g. AuthenticatedSubdomain and that will pretty soon became really awkward with deeper nesting. The wrapper class solves the problem with naming and reusing the same constraint classes, but doesn’t solve the problem of repeating constraints.

After some further testing, this seems a little bazaar.

The following code will run both the Subdomain and Authenticated constraints when accessing a resource:

scope :constraints => Subdomain.new do

resources :something, :constraints => Authenticated.new

end

However, with the root route specified (your scenario), it only runs the constraint attached directly to the root route. Not sure if this is a bug, or the intended behavior of the root route.

Thanks for the tip!

I’ll check if there’s anything obvious messed up in Rails routing code and just report a bug - we’ll see what they say :slight_smile: