I'm trying to collect all the Rails routes, and dump their named_route
, path
and constraint
(if there is one).
I'm able to get the named_route
, path
, but I'm trying to find a way to get the routes constraint
.
routes = Rails.application.routes.routes.map do |route|
path = route.path.spec.to_s.gsub!("(.:format)", '')
# route.constraints always output {} ??
puts route.constraints
name = route.name
[name, path]
end.to_h
Here is an example of a route..
USER_NAME_PATTERN ||= /@[a-z0-9][-a-z0-9]+/
get ":username/:slug", to: 'calcs#show', as: :user_calc , constraints: {username: USER_NAME_PATTERN }
How to programmatically get a Rails Routes constraint?
Constraints are a bit complicated, because there are multiple kinds of route constraint, which are specified the same way in routes.rb
, but get handled internally somewhat differently.
The kind of constraint in your question is a segment constraint, which imposes a format on one or more segments of the path. Segment constraints are stored in the requirements
hash at the path level, using keys that correspond to the segment names (segment names are stored in the parts
attribute on the Route
).
> route = Rails.application.routes.named_routes.get(:user_calc)
=> #<ActionDispatch::Journey::Route:0x00007f6aa05b2cc0>
> route.parts
=> [:username, :slug, :format]
> route.path.requirements
=> {:username=>/@[a-z0-9][-a-z0-9]+/}
There are also request constraints, which constrains a route based on any method on the Request
object that returns a string. These get specified similarly to segment constraints:
get ":username/:slug", to: 'calcs#show', as: :user_calc , constraints: {subdomain: 'admin'}
Request constraints are stored in the constraints
attribute on the Route
object.
> route = Rails.application.routes.named_routes.get(:user_calc)
=> #<ActionDispatch::Journey::Route:0x00007f6aa05b2cc0>
> route.constraints
=> {:subdomain=>"admin"}
You can also specify constraints using a lambda
or class that responds to .matches?
. These advanced constraints seem to be handled by a different mechanism, but I haven't dug around enough in the code to understand exactly how.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With