Class: Everywhere::RequestContext
- Inherits:
-
Object
- Object
- Everywhere::RequestContext
- Defined in:
- lib/everywhere/request_context.rb
Overview
What a per-request hook — the tab bar block, the current-user resolver — gets handed instead of a bare request.
It exists because the raw request isn't the same object on every path: Rails apps reach the mobile config endpoint through MobileConfigsController with an ActionDispatch::Request (signed/encrypted cookie jar), Sinatra and Hanami apps through MobileConfigEndpoint with a Rack::Request (plain cookie hash). A block written against one used to break on the other; #session and #cookies here read the same on both.
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
The app's Everywhere::Config.
-
#platform ⇒ Object
readonly
"ios" or "android" — which shell is asking.
-
#request ⇒ Object
readonly
The framework-native request, for anything this class doesn't wrap (Warden lives at
request.env["warden"], for one).
Instance Method Summary collapse
- #android? ⇒ Boolean
-
#cookies ⇒ Object
Cookies.
-
#current_user ⇒ Object
Whoever
Everywhere.current_userresolves for this request — nil when no resolver is registered, so a hook that branches on it degrades to "signed out" rather than raising. -
#initialize(request, platform: nil, config: nil) ⇒ RequestContext
constructor
A new instance of RequestContext.
- #ios? ⇒ Boolean
-
#session ⇒ Object
The session hash, or {} when the app runs no session middleware (and on the bare-env fallback, where
requestis a Hash rather than a Request). - #signed_in? ⇒ Boolean
-
#tab(name) ⇒ Object
A tab declared in config/everywhere.yml, by name, resolved for this platform — including
visible: falseones, which is the point: declare a tab so the build validates its icon and bakes nothing, then add it back here for the users who should see it.
Constructor Details
#initialize(request, platform: nil, config: nil) ⇒ RequestContext
Returns a new instance of RequestContext.
27 28 29 30 31 |
# File 'lib/everywhere/request_context.rb', line 27 def initialize(request, platform: nil, config: nil) @request = request @platform = platform&.to_s @config = config end |
Instance Attribute Details
#config ⇒ Object (readonly)
The app's Everywhere::Config. nil outside the mobile config endpoint.
25 26 27 |
# File 'lib/everywhere/request_context.rb', line 25 def config @config end |
#platform ⇒ Object (readonly)
"ios" or "android" — which shell is asking. nil outside the mobile config endpoint.
22 23 24 |
# File 'lib/everywhere/request_context.rb', line 22 def platform @platform end |
#request ⇒ Object (readonly)
The framework-native request, for anything this class doesn't wrap
(Warden lives at request.env["warden"], for one).
18 19 20 |
# File 'lib/everywhere/request_context.rb', line 18 def request @request end |
Instance Method Details
#android? ⇒ Boolean
34 |
# File 'lib/everywhere/request_context.rb', line 34 def android? = platform == "android" |
#cookies ⇒ Object
Cookies. Rails' jar when the request carries one, so cookies.signed[…]
and cookies.encrypted[…] work; Rack's name => value hash otherwise. Both
answer cookies[:name], which is the common case.
47 48 49 50 51 52 53 54 55 |
# File 'lib/everywhere/request_context.rb', line 47 def return @cookies if defined?(@cookies) @cookies = if request.respond_to?(:cookie_jar) then request. elsif request.respond_to?(:cookies) then request. else {} end end |
#current_user ⇒ Object
Whoever Everywhere.current_user resolves for this request — nil when no
resolver is registered, so a hook that branches on it degrades to "signed
out" rather than raising. Memoized: resolvers hit the database, and the
tab block is free to ask several times.
61 62 63 64 65 |
# File 'lib/everywhere/request_context.rb', line 61 def current_user return @current_user if defined?(@current_user) @current_user = Everywhere.resolve_current_user(self) end |
#ios? ⇒ Boolean
33 |
# File 'lib/everywhere/request_context.rb', line 33 def ios? = platform == "ios" |
#session ⇒ Object
The session hash, or {} when the app runs no session middleware (and on
the bare-env fallback, where request is a Hash rather than a Request).
38 39 40 41 42 |
# File 'lib/everywhere/request_context.rb', line 38 def session return @session if defined?(@session) @session = (request.session if request.respond_to?(:session)) || {} end |
#signed_in? ⇒ Boolean
67 |
# File 'lib/everywhere/request_context.rb', line 67 def signed_in? = !current_user.nil? |
#tab(name) ⇒ Object
A tab declared in config/everywhere.yml, by name, resolved for this
platform — including visible: false ones, which is the point: declare a
tab so the build validates its icon and bakes nothing, then add it back
here for the users who should see it.
Everywhere.tabs do |tabs, ctx|
ctx.current_user.admin? ? tabs + [ctx.tab("Admin")] : tabs
end
Raises on an unknown name rather than returning nil: a typo would otherwise drop the tab silently, and this fails in the endpoint where the message can name it.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/everywhere/request_context.rb', line 81 def tab(name) unless config && platform raise Error, "RequestContext#tab needs the app config — it's available " \ "inside an Everywhere.tabs block, not to a standalone context" end declared = config.tabs_for(platform, include_hidden: true) wanted = name.to_s found = declared.find { |tab| tab["title"] == wanted } || declared.find { |tab| tab["title"].to_s.casecmp?(wanted) } return found if found raise Error, "no tab named #{wanted.inspect} in config/everywhere.yml — " \ "declared: #{declared.map { |tab| tab["title"] }.inspect}" end |