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



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

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

.currentObject



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

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

.define_accessorsObject



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

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



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

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



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

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

.define_id_getter(attr) ⇒ Object



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

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

.define_id_setter(attr) ⇒ Object



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

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



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

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

.durationObject



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

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

.either_adminObject



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

def self.either_admin
  current_root || current_admin
end

.either_siteObject



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

def self.either_site
  target_site || current_site
end

.either_site_idObject



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

def self.either_site_id
  target_site_id || current_site_id
end

.either_tenantObject



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

def self.either_tenant
  target_tenant || current_tenant
end

.either_tenant_idObject



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

def self.either_tenant_id
  target_tenant_id || current_tenant_id
end

.either_workspaceObject



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

def self.either_workspace
  target_workspace || current_workspace
end

.either_workspace_idObject



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

def self.either_workspace_id
  target_workspace_id || current_workspace_id
end

.fill_details(state) ⇒ Object



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

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



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

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



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

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



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

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

.nowObject



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

def self.now
  DateTime.current
end

.request_idObject



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

def self.request_id
  current[:request_id]
end

.request_id=(rqid) ⇒ Object



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

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

.startedObject



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

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

.started=(time) ⇒ Object



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

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

.to_hashObject



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

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



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

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