Class: Bp3::RequestState::Base

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/bp3/request_state/base.rb

Overview

rubocop:disable Metrics/ClassLength, Style/ClassVars

Direct Known Subclasses

Test

Constant Summary collapse

@@hash_key_map =
{ current_site: 'Site',
current_tenant: 'Tenant',
current_workspace: 'Workspace',
current_user: 'User',
current_admin: 'Admin',
current_root: 'Root',
current_visitor: 'Visitor' }.freeze
@@base_attrs =
%w[current_site current_tenant current_workspace
current_user current_admin current_root current_visitor
locale view_context].freeze
@@hash_attrs =
%w[current_site_id current_tenant_id current_workspace_id
current_user_id current_admin_id current_root_id current_visitor_id].freeze

Class Method Summary collapse

Class Method Details

.clear!Object



37
38
39
# File 'lib/bp3/request_state/base.rb', line 37

def self.clear!
  RequestStore.delete(:bp3_request_state)
end

.currentObject



41
42
43
44
45
# File 'lib/bp3/request_state/base.rb', line 41

def self.current
  RequestStore.fetch(:bp3_request_state) do
    { started: DateTime.current }
  end
end

.define_accessorsObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/bp3/request_state/base.rb', line 68

def self.define_accessors
  base_attrs.each do |attr|
    define_accessors_for_one_attr(attr)
  end

  # current_login picks one of the logged-in user, site-admin or root.
  # pick the one with least privileges first
  define_singleton_method :current_login do
    current_user || current_admin || current_root
  end
  define_method :current_login do
    current_user || current_admin || current_root
  end

  define_singleton_method :highest_privilege do
    # do not include current_visitor, as they are not logged in
    current_root || current_admin || current_user # || current_visitor
  end
  define_method :highest_privilege do
    # do not include current_visitor, as they are not logged in
    current_root || current_admin || current_user # || current_visitor
  end
end

.define_accessors_for_one_attr(attr) ⇒ Object



178
179
180
181
182
183
184
185
186
# File 'lib/bp3/request_state/base.rb', line 178

def self.define_accessors_for_one_attr(attr)
  define_getter(attr)
  define_setter(attr)
  define_id_getter(attr)
  define_id_setter(attr)
  define_method(attr) do
    self.class.current[attr.to_sym]
  end
end

.define_getter(attr) ⇒ Object



188
189
190
191
192
# File 'lib/bp3/request_state/base.rb', line 188

def self.define_getter(attr)
  define_singleton_method(attr) do
    current[attr.to_sym]
  end
end

.define_id_getter(attr) ⇒ Object



200
201
202
203
204
# File 'lib/bp3/request_state/base.rb', line 200

def self.define_id_getter(attr)
  define_singleton_method("#{attr}_id") do
    current[attr.to_sym]&.id
  end
end

.define_id_setter(attr) ⇒ Object



206
207
208
209
210
# File 'lib/bp3/request_state/base.rb', line 206

def self.define_id_setter(attr)
  define_singleton_method("#{attr}_id=") do |id|
    current[attr.to_sym] = fill_one_from_map(attr.to_sym, id)
  end
end

.define_setter(attr) ⇒ Object



194
195
196
197
198
# File 'lib/bp3/request_state/base.rb', line 194

def self.define_setter(attr)
  define_singleton_method("#{attr}=") do |obj|
    current[attr.to_sym] = obj
  end
end

.durationObject



150
151
152
# File 'lib/bp3/request_state/base.rb', line 150

def self.duration
  (now - started) * 1.day # in seconds
end

.either_adminObject



145
146
147
# File 'lib/bp3/request_state/base.rb', line 145

def self.either_admin
  current_root || current_admin
end

.either_siteObject



118
119
120
# File 'lib/bp3/request_state/base.rb', line 118

def self.either_site
  target_site || current_site
end

.either_site_idObject



123
124
125
# File 'lib/bp3/request_state/base.rb', line 123

def self.either_site_id
  target_site_id || current_site_id
end

.either_tenantObject



127
128
129
# File 'lib/bp3/request_state/base.rb', line 127

def self.either_tenant
  target_tenant || current_tenant
end

.either_tenant_idObject



132
133
134
# File 'lib/bp3/request_state/base.rb', line 132

def self.either_tenant_id
  target_tenant_id || current_tenant_id
end

.either_workspaceObject



136
137
138
# File 'lib/bp3/request_state/base.rb', line 136

def self.either_workspace
  target_workspace || current_workspace
end

.either_workspace_idObject



141
142
143
# File 'lib/bp3/request_state/base.rb', line 141

def self.either_workspace_id
  target_workspace_id || current_workspace_id
end

.fill_details(state) ⇒ Object



112
113
114
115
116
# File 'lib/bp3/request_state/base.rb', line 112

def self.fill_details(state)
  self.request_id = state.request_id if state.request_id
  self.started = state.started_string.present? ? DateTime.parse(state.started_string) : nil
  self.locale = state.locale&.to_sym
end

.fill_from_map(state) ⇒ Object



99
100
101
102
103
104
# File 'lib/bp3/request_state/base.rb', line 99

def self.fill_from_map(state)
  hash_key_map.each_key do |attr|
    attr_with_id = "#{attr}_id"
    fill_one_from_map(attr.to_sym, state.send(attr_with_id)) if state.send(attr_with_id)
  end
end

.fill_one_from_map(attr, id) ⇒ Object



106
107
108
109
110
# File 'lib/bp3/request_state/base.rb', line 106

def self.fill_one_from_map(attr, id)
  klass = hash_key_map[attr.to_sym]&.constantize
  writer = "#{attr}="
  send(writer, klass.find_by(id:))
end

.from_hash(hash) ⇒ Object



92
93
94
95
96
97
# File 'lib/bp3/request_state/base.rb', line 92

def self.from_hash(hash)
  state = OpenStruct.new(hash) # rubocop:disable Style/OpenStructUse
  fill_from_map(state)
  fill_details(state)
  self
end

.nowObject



155
156
157
# File 'lib/bp3/request_state/base.rb', line 155

def self.now
  DateTime.current
end

.request_idObject



169
170
171
# File 'lib/bp3/request_state/base.rb', line 169

def self.request_id
  current[:request_id]
end

.request_id=(rqid) ⇒ Object



174
175
176
# File 'lib/bp3/request_state/base.rb', line 174

def self.request_id=(rqid)
  current[:request_id] = rqid
end

.startedObject



160
161
162
# File 'lib/bp3/request_state/base.rb', line 160

def self.started
  current[:started] || now
end

.started=(time) ⇒ Object



165
166
167
# File 'lib/bp3/request_state/base.rb', line 165

def self.started=(time)
  current[:started] = time || now
end

.to_hashObject



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/bp3/request_state/base.rb', line 55

def self.to_hash
  {
    request_id:,
    started_string: started.utc.to_s,
    locale: locale&.to_s
  }.tap do |hash|
    hash_attrs.each do |id_attr|
      attr = id_attr.gsub('_id', '')
      hash[id_attr] = send(id_attr) if respond_to?(attr)
    end
  end.stringify_keys
end

.with_current(site:, tenant: nil, workspace: nil) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/bp3/request_state/base.rb', line 47

def self.with_current(site:, tenant: nil, workspace: nil)
  clear!
  self.current_site = site
  self.current_tenant = tenant || site.default_tenant
  self.current_workspace = workspace || site.default_workspace
  yield if block_given?
end