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` → `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

Instance Method Details

#resolved_time_zoneObject

The ActiveSupport::TimeZone chosen for this request — always one ‘Time` can switch to (falls back to the current `Time.zone`).



73
74
75
76
77
78
79
80
81
82
# File 'lib/concerns_on_rails/controllers/timezoneable.rb', line 73

def resolved_time_zone
  opts = self.class.timezoneable_options
  allowed = opts[:available]
  candidate = zone_from_param(opts, allowed) ||
              zone_from_header(opts, allowed) ||
              zone_from_cookie(opts, allowed) ||
              opts[:default]

  resolve_zone(candidate) || Time.zone
end

#switch_time_zoneObject

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
# File 'lib/concerns_on_rails/controllers/timezoneable.rb', line 67

def switch_time_zone(&)
  Time.use_zone(resolved_time_zone, &)
end