From 7f88b2ad2304cd8967d12eb9333d5a70645dd2d7 Mon Sep 17 00:00:00 2001 From: Eric Proulx Date: Sat, 23 May 2026 18:48:42 +0200 Subject: [PATCH] Skip redundant `GRAPE_ROUTING_ARGS` rewrite when route has no params to merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Router#process_route` previously did: args = env[Grape::Env::GRAPE_ROUTING_ARGS] || { route_info: route } route_params = route.params(input) env[Grape::Env::GRAPE_ROUTING_ARGS] = route_params.blank? ? args : args.merge(route_params) When `env[GRAPE_ROUTING_ARGS]` was already set and `route_params` was blank, the ternary returned `args` unchanged and we wrote the same Hash back to env — a no-op assignment on every cascade match through a route with no URL placeholders (the common case). Switch to `||=` for the default, and only re-assign env when there are new params to merge. Same observable behavior; one fewer env write per no-param route match. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 1 + lib/grape/router.rb | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88c06acba..6f848db49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ * [#2726](https://github.com/ruby-grape/grape/pull/2726): Reuse one `AttributesIterator` per validator and drop the unused `Enumerable` mixin - [@ericproulx](https://github.com/ericproulx). * [#2728](https://github.com/ruby-grape/grape/pull/2728): Deprecate passing a positional options Hash to `auth`/`http_basic`/`http_digest`; pass keyword arguments instead - [@ericproulx](https://github.com/ericproulx). * [#2733](https://github.com/ruby-grape/grape/pull/2733): Drop the dead `active_support/core_ext/hash/reverse_merge` require; call `ActiveSupport::HashWithIndifferentAccess.new(...)` directly at call sites - [@ericproulx](https://github.com/ericproulx). +* [#2738](https://github.com/ruby-grape/grape/pull/2738): Skip the redundant `env[Grape::Env::GRAPE_ROUTING_ARGS]` rewrite in `Router#process_route` when the matched route has no URL params to merge - [@ericproulx](https://github.com/ericproulx). * Your contribution here. #### Fixes diff --git a/lib/grape/router.rb b/lib/grape/router.rb index 3dcdf08f6..3d4d63531 100644 --- a/lib/grape/router.rb +++ b/lib/grape/router.rb @@ -122,9 +122,13 @@ def halt?(response) end def process_route(route, input, env, include_allow_header: false) - args = env[Grape::Env::GRAPE_ROUTING_ARGS] || { route_info: route } route_params = route.params(input) - env[Grape::Env::GRAPE_ROUTING_ARGS] = route_params.blank? ? args : args.merge(route_params) + if route_params.present? + args = env[Grape::Env::GRAPE_ROUTING_ARGS] || { route_info: route } + env[Grape::Env::GRAPE_ROUTING_ARGS] = args.merge(route_params) + else + env[Grape::Env::GRAPE_ROUTING_ARGS] ||= { route_info: route } + end env[Grape::Env::GRAPE_ALLOWED_METHODS] = route.allow_header if include_allow_header route.call(env) end