Module: ConcernsOnRails::Controllers::Timezoneable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/concerns_on_rails/controllers/timezoneable.rb
Overview
Per-request Time.zone selection from the request params, the Time-Zone
header, and/or a cookie, wrapped in an around_action so Time.zone is set
for the action and restored afterwards. The time analogue of Localizable
(which does the same for I18n.locale). Dependency-free.
class ApplicationController < ActionController::Base
include ConcernsOnRails::Controllers::Timezoneable
timezoneable available: ["UTC", "Eastern Time (US & Canada)"], default: "UTC"
# timezoneable param: :tz, header: false, cookie: :time_zone
end
Resolution order: params[param] → Time-Zone header → cookie (if enabled)
→ default → the current Time.zone. Every value — the configured
available:/default: AND each request candidate — is resolved through
ActiveSupport::TimeZone[...], so a zone accepted at boot can never be
rejected at request time.
Options: available: (allow-list applied to param/header/cookie matching;
default: bypasses it, mirroring Localizable), default:, param:
(default :time_zone), header: (default true), cookie: (default
false; true reads the :time_zone cookie, or pass a cookie name).
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#resolved_time_zone ⇒ Object
The ActiveSupport::TimeZone chosen for this request — always one
Timecan switch to (falls back to the currentTime.zone). -
#switch_time_zone ⇒ Object
Public so subclasses can override; runs the action under the resolved zone.
Instance Method Details
#resolved_time_zone ⇒ Object
The ActiveSupport::TimeZone chosen for this request — always one Time
can switch to (falls back to the current Time.zone). Memoized per
request: resolution costs up to three TimeZone lookups plus an
allow-list scan.
81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/concerns_on_rails/controllers/timezoneable.rb', line 81 def resolved_time_zone @resolved_time_zone ||= begin opts = self.class. allowed = opts[:available] candidate = zone_from_param(opts, allowed) || zone_from_header(opts, allowed) || (opts, allowed) || opts[:default] resolve_zone(candidate) || Time.zone end end |
#switch_time_zone ⇒ Object
Public so subclasses can override; runs the action under the resolved
zone. UNGUARDED on purpose — it touches Time globally, not the response
(mirrors Localizable#switch_locale).
67 68 69 70 71 72 73 74 75 |
# File 'lib/concerns_on_rails/controllers/timezoneable.rb', line 67 def switch_time_zone(&) zone = resolved_time_zone # Skip the wrapper when it would be a no-op — with nothing configured # (or the client asking for the current zone) every action used to run # inside a pointless Time.use_zone block. return yield if Time.zone && zone && zone.name == Time.zone.name Time.use_zone(zone, &) end |