Created
December 8, 2025 18:20
-
-
Save bradgessler/2cfd814cc4ccc094c14fed2f57e464a7 to your computer and use it in GitHub Desktop.
Dasherized Rails routes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # config/initializers/route_format.rb | |
| # | |
| # Global route formatting override for Rails routing. | |
| # | |
| # This hooks into ActionDispatch::Routing::Mapper::Mapping and mutates the | |
| # Journey AST in place so that underscored literal path segments are | |
| # dasherized. It affects *all* routes (get, resources, scope, etc.) | |
| # because they all end up as a Journey AST passed into Mapping. | |
| # | |
| # IMPORTANT: | |
| # - This does NOT distinguish between symbols and strings in the routes DSL. | |
| # - Any literal segment like "linked_in" becomes "linked-in". | |
| # - Dynamic params (e.g. :id) are not changed. | |
| # | |
| Rails.application.config.routes_format = :dasherize | |
| module RouteFormatAstRewrite | |
| private | |
| # Recursively walk a Journey AST node and rewrite literal segments in-place. | |
| # | |
| # Only touches ActionDispatch::Journey::Nodes::Literal instances whose | |
| # underlying string contains an underscore. Other node types are left as-is. | |
| def rf_rewrite_ast(node) | |
| formatter = Rails.application.config.routes_format | |
| return unless formatter | |
| return unless node | |
| case node | |
| when ActionDispatch::Journey::Nodes::Literal | |
| value = node.left | |
| if value.is_a?(String) && value.include?("_") | |
| node.left = value.public_send(formatter) | |
| # Clear cached to_s so Journey will recompute the string | |
| node.instance_variable_set(:@to_s, nil) | |
| end | |
| when ActionDispatch::Journey::Nodes::Binary | |
| rf_rewrite_ast(node.left) | |
| rf_rewrite_ast(node.right) | |
| when ActionDispatch::Journey::Nodes::Unary, | |
| ActionDispatch::Journey::Nodes::Group, | |
| ActionDispatch::Journey::Nodes::Star | |
| rf_rewrite_ast(node.left) | |
| when ActionDispatch::Journey::Nodes::Or | |
| node.children.each { |child| rf_rewrite_ast(child) } | |
| else | |
| # leave other node types unchanged | |
| end | |
| end | |
| # Hook into Mapping initialization to rewrite the AST before the | |
| # Journey::Path::Pattern is built. | |
| def initialize(*, ast:, **, &) | |
| rf_rewrite_ast(ast) | |
| super(*, ast:, **, &) | |
| end | |
| end | |
| # Patch the core Mapping class used by all router macros. | |
| ActionDispatch::Routing::Mapper::Mapping.prepend(RouteFormatAstRewrite) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment