module ActionDispatch::Routing::Mapper::Scoping

def constraints(constraints = {}, &block)

end
resources :iphones
constraints(Iphone) do

This class is then used like this:

An expected place for this code would be +lib/constraints+.

end
end
/iPhone/.match?(request.env["HTTP_USER_AGENT"])
def self.matches?(request)
class Iphone

if the user should be given access to that route, or +false+ if the user should not.
This class must have a +matches?+ method defined on it which either returns +true+
You are able to move this logic out into a class if it is too complex for routes.

end
resources :iphones
constraints(-> (req) { /iPhone/.match?(req.env["HTTP_USER_AGENT"]) }) do

Requests to routes can be constrained based on specific criteria:

=== Dynamic request matching

where as any user connecting outside of this range will be told there is no such route.
Any user connecting from the 192.168.* range will be able to see this resource,

end
resources :posts
constraints(ip: /192\.168\.\d+\.\d+/) do

Routes can also be constrained to an IP or a certain range of IP addresses:

=== Restricting based on IP

end
end
resources :comments
constraints(post_id: /\d+\.\d+/) do
resources :posts do

You may use this to also restrict other parameters:

The +id+ parameter must match the constraint passed in for this example.
Now routes such as +/posts/1+ will no longer be valid, but +/posts/1.1+ will be.

end
resources :posts
constraints(id: /\d+\.\d+/) do

For instance, in order to change the routes to allow for a dot character in the +id+ parameter:
Allows you to constrain the nested routes based on a set of rules.
=== Parameter Restriction
def constraints(constraints = {}, &block)
  scope(constraints: constraints, &block)
end