[Proposal] Support dynamic `store:` option in `rate_limit`

I’d like to propose a small enhancement to the rate_limit controller method. PR #57365 is open for consideration, happy to hear any thoughts.

The problem

The store: option in rate_limit currently only accepts a static cache store reference. If you want to use different stores per request (e.g., a dedicated Redis for premium users, a shared one for free users, cache migration), you need to work around this.

The proposal

Allow store: to accept a method name (symbol) or a callable (lambda/proc), matching how to: and within: already work.

This way, the store is resolved at request time in the controller context.

class APIController < ApplicationController
  rate_limit to: 1000, within: 1.minute, store: :rate_store

  private

  def rate_store
    current_user.premium? ? premium_cache : default_cache
  end
end

Or with a lambda:

class APIController < ApplicationController
  rate_limit to: 1000, within: 1.minute, store: → {current_user.premium? ? premium_cache : default_cache}
end

Implementation notes

The change is similar to what we already have in the codebase. Existing static usage is unaffected, as per the specs.

Same is_a?(Symbol) / respond_to?(:call) pattern used for to: and within: is applied to store: in rate_limiting.rb.

First post here, so I’m not quite sure I got all of it right.

Would like to hear any thoughts or concerns. Cheers.

This seems reasonable to me and I don’t see why such a change wouldn’t be accepted by the team. Send a PR if you’d like and we can go from there. See the Contributing to Ruby on Rails guide.

1 Like

Hi Joshua,

Thanks for your input. I’ve opened a PR for consideration: #57365.

Hope everything looks good, but please let me know if there’s anything that should be changed or improved.