Class: Avo::BaseResource

Inherits:
Object
  • Object
show all
Extended by:
ActiveSupport::DescendantsTracker, FieldsCollector, HasContext
Includes:
ActionView::Helpers::UrlHelper
Defined in:
lib/avo/base_resource.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FieldsCollector

field, heading, parse_field

Constructor Details

#initializeBaseResource

Returns a new instance of BaseResource.



84
85
86
87
88
# File 'lib/avo/base_resource.rb', line 84

def initialize
  unless self.class.model_class.present?
    self.class.model_class = model_class.base_class
  end
end

Instance Attribute Details

#modelObject

Returns the value of attribute model.



16
17
18
# File 'lib/avo/base_resource.rb', line 16

def model
  @model
end

#paramsObject

Returns the value of attribute params.



18
19
20
# File 'lib/avo/base_resource.rb', line 18

def params
  @params
end

#userObject

Returns the value of attribute user.



17
18
19
# File 'lib/avo/base_resource.rb', line 17

def user
  @user
end

#viewObject

Returns the value of attribute view.



15
16
17
# File 'lib/avo/base_resource.rb', line 15

def view
  @view
end

Class Method Details

.action(action_class) ⇒ Object



47
48
49
50
51
# File 'lib/avo/base_resource.rb', line 47

def action(action_class)
  self.actions_loader ||= Avo::Loaders::Loader.new

  self.actions_loader.use action_class
end

.authorizationObject



79
80
81
# File 'lib/avo/base_resource.rb', line 79

def authorization
  Avo::Services::AuthorizationService.new Avo::App.current_user
end

.filter(filter_class) ⇒ Object



53
54
55
56
57
# File 'lib/avo/base_resource.rb', line 53

def filter(filter_class)
  self.filters_loader ||= Avo::Loaders::Loader.new

  self.filters_loader.use filter_class
end

.find_scopeObject

This resolves the scope when finding records (not “where” queries)



73
74
75
76
77
# File 'lib/avo/base_resource.rb', line 73

def find_scope
  final_scope = resolve_find_scope.present? ? resolve_find_scope.call(model_class: model_class) : model_class

  authorization.apply_policy final_scope
end

.grid(&block) ⇒ Object



40
41
42
43
44
45
# File 'lib/avo/base_resource.rb', line 40

def grid(&block)
  grid_collector = GridCollector.new
  grid_collector.instance_eval(&block)

  self.grid_loader = grid_collector
end

.query_scopeObject

This resolves the scope when doing “where” queries (not find queries)



66
67
68
69
70
# File 'lib/avo/base_resource.rb', line 66

def query_scope
  final_scope = resolve_query_scope.present? ? resolve_query_scope.call(model_class: model_class) : model_class

  authorization.apply_policy final_scope
end

.scopeObject

This is the search_query scope This should be removed and passed to the search block



61
62
63
# File 'lib/avo/base_resource.rb', line 61

def scope
  self.query_scope
end

Instance Method Details

#attached_file_fieldsObject



273
274
275
276
277
# File 'lib/avo/base_resource.rb', line 273

def attached_file_fields
  get_field_definitions.select do |field|
    [Avo::Fields::FileField, Avo::Fields::FilesField].include? field.class
  end
end

#authorizationObject



301
302
303
# File 'lib/avo/base_resource.rb', line 301

def authorization
  Avo::Services::AuthorizationService.new(user, model || model_class)
end

#available_view_typesObject



261
262
263
264
265
266
267
# File 'lib/avo/base_resource.rb', line 261

def available_view_types
  view_types = [:table]

  view_types << :grid if get_grid_fields.present?

  view_types
end

#avatarObject



414
415
416
417
418
419
420
421
422
# File 'lib/avo/base_resource.rb', line 414

def avatar
  return avatar_field.to_image if avatar_field.respond_to? :to_image

  return avatar_field.value.variant(resize_to_limit: [480, 480]) if avatar_field.type == "file"

  avatar_field.value
rescue
  nil
end

#avatar_fieldObject



406
407
408
409
410
411
412
# File 'lib/avo/base_resource.rb', line 406

def avatar_field
  get_field_definitions.find do |field|
    field.as_avatar.present?
  end
rescue
  nil
end

#avatar_typeObject



424
425
426
427
428
# File 'lib/avo/base_resource.rb', line 424

def avatar_type
  avatar_field.as_avatar
rescue
  nil
end

#cache_hash(parent_model) ⇒ Object



323
324
325
326
327
328
329
# File 'lib/avo/base_resource.rb', line 323

def cache_hash(parent_model)
  if parent_model.present?
    [model, file_hash, parent_model]
  else
    [model, file_hash]
  end
end

#class_name_without_resourceObject



206
207
208
# File 'lib/avo/base_resource.rb', line 206

def class_name_without_resource
  self.class.name.demodulize.chomp("Resource")
end

#contextObject



269
270
271
# File 'lib/avo/base_resource.rb', line 269

def context
  self.class.context
end

#default_panel_nameObject



183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/avo/base_resource.rb', line 183

def default_panel_name
  return @params[:related_name].capitalize if @params.present? && @params[:related_name].present?

  case @view
  when :show
    I18n.t("avo.resource_details", item: name.downcase, title: model_title).upcase_first
  when :edit
    I18n.t("avo.update_item", item: name.downcase, title: model_title).upcase_first
  when :new
    I18n.t("avo.create_new_item", item: name.downcase).upcase_first
  end
end

#descriptionObject



438
439
440
441
442
# File 'lib/avo/base_resource.rb', line 438

def description
  description_field.value
rescue
  nil
end

#description_fieldObject



430
431
432
433
434
435
436
# File 'lib/avo/base_resource.rb', line 430

def description_field
  get_field_definitions.find do |field|
    field.as_description.present?
  end
rescue
  nil
end

#file_hashObject



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/avo/base_resource.rb', line 305

def file_hash
  content_to_be_hashed = ""

  # resource file hash
  resource_path = Rails.root.join("app", "avo", "resources", "#{self.class.name.underscore}.rb").to_s
  if File.file? resource_path
    content_to_be_hashed += File.read(resource_path)
  end

  # policy file hash
  policy_path = Rails.root.join("app", "policies", "#{self.class.name.underscore.gsub("_resource", "")}_policy.rb").to_s
  if File.file? policy_path
    content_to_be_hashed += File.read(policy_path)
  end

  Digest::MD5.hexdigest(content_to_be_hashed)
end

#fill_model(model, params) ⇒ Object



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/avo/base_resource.rb', line 279

def fill_model(model, params)
  # Map the received params to their actual fields
  fields_by_database_id = get_field_definitions
    .reject do |field|
      field.computed
    end
    .map do |field|
      [field.database_id(model).to_s, field]
    end
    .to_h

  params.each do |key, value|
    field = fields_by_database_id[key]

    next unless field.present?

    model = field.fill_field model, key, value, params
  end

  model
end

#form_scopeObject



444
445
446
# File 'lib/avo/base_resource.rb', line 444

def form_scope
  model.class.base_class.to_s.underscore.downcase
end

#get_actionsObject



169
170
171
172
173
# File 'lib/avo/base_resource.rb', line 169

def get_actions
  return [] if self.class.actions_loader.blank?

  self.class.actions_loader.bag
end

#get_field_definitionsObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/avo/base_resource.rb', line 104

def get_field_definitions
  return [] if self.class.fields.blank?

  fields = self.class.fields.map do |field|
    field.hydrate(resource: self, panel_name: default_panel_name, user: user, translation_enabled: translation_enabled)
  end

  if Avo::App.license.lacks_with_trial(:custom_fields)
    fields = fields.reject do |field|
      field.custom?
    end
  end

  fields
end

#get_fields(panel: nil, reflection: nil) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/avo/base_resource.rb', line 120

def get_fields(panel: nil, reflection: nil)
  fields = get_field_definitions
    .select do |field|
      field.send("show_on_#{@view}")
    end
    .select do |field|
      field.visible?
    end
    .select do |field|
      # Strip out the reflection field in index queries with a parent association.
      if reflection.present? &&
          reflection.options.present? &&
          field.respond_to?(:polymorphic_as) &&
          field.polymorphic_as.to_s == reflection.options[:as].to_s
        next
      end
      if field.respond_to?(:foreign_key) &&
          reflection.present? &&
          reflection.respond_to?(:foreign_key) &&
          reflection.foreign_key != field.foreign_key
        next
      end

      true
    end

  if panel.present?
    fields = fields.select do |field|
      field.panel_name == panel
    end
  end

  hydrate_fields(model: @model, view: @view)

  fields
end

#get_filtersObject



163
164
165
166
167
# File 'lib/avo/base_resource.rb', line 163

def get_filters
  return [] if self.class.filters_loader.blank?

  self.class.filters_loader.bag
end

#get_grid_fieldsObject



157
158
159
160
161
# File 'lib/avo/base_resource.rb', line 157

def get_grid_fields
  return if self.class.grid_loader.blank?

  self.class.grid_loader.hydrate(model: @model, view: @view, resource: self)
end

#hydrate(model: nil, view: nil, user: nil, params: nil) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/avo/base_resource.rb', line 90

def hydrate(model: nil, view: nil, user: nil, params: nil)
  @view = view if view.present?
  @user = user if user.present?
  @params = params if params.present?

  if model.present?
    @model = model

    hydrate_model_with_default_values if @view == :new
  end

  self
end

#hydrate_fields(model: nil, view: nil) ⇒ Object



175
176
177
178
179
180
181
# File 'lib/avo/base_resource.rb', line 175

def hydrate_fields(model: nil, view: nil)
  fields.map do |field|
    field.hydrate(model: @model, view: @view, resource: self)
  end

  self
end

#hydrate_model_with_default_valuesObject

We will not overwrite any attributes that come pre-filled in the model.



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/avo/base_resource.rb', line 332

def hydrate_model_with_default_values
  default_values = get_fields
    .select do |field|
      !field.computed
    end
    .map do |field|
      id = field.id
      value = field.value

      if field.type == "belongs_to"
        id = field.foreign_key.to_sym

        reflection = @model._reflections[@params[:via_relation]]

        if field.polymorphic_as.present? && field.types.map(&:to_s).include?(@params[:via_relation_class])
          # set the value to the actual record
          value = @params[:via_relation_class].safe_constantize.find(@params[:via_resource_id])
        elsif reflection.present? && reflection.foreign_key.present? && field.id.to_s == @params[:via_relation].to_s
          value = @params[:via_resource_id]
        end
      end

      [id, value]
    end
    .to_h
    .select do |id, value|
      value.present?
    end

  default_values.each do |id, value|
    if @model.send(id).nil?
      @model.send("#{id}=", value)
    end
  end
end

#labelObject



400
401
402
403
404
# File 'lib/avo/base_resource.rb', line 400

def label
  label_field.value || model_title
rescue
  model_title
end

#label_fieldObject



392
393
394
395
396
397
398
# File 'lib/avo/base_resource.rb', line 392

def label_field
  get_field_definitions.find do |field|
    field.as_label.present?
  end
rescue
  nil
end

#model_classObject



210
211
212
213
214
215
216
217
218
219
# File 'lib/avo/base_resource.rb', line 210

def model_class
  # get the model class off of the static property
  return self.class.model_class if self.class.model_class.present?

  # get the model class off of the model
  return @model.base_class if @model.present?

  # generate a model class
  class_name_without_resource.safe_constantize
end

#model_keyObject

This is used as the model class ID We use this instead of the route_key to maintain compatibility with uncountable models With uncountable models route key appends an _index suffix (Fish->fish_index) Example: User->users, MediaItem->medie_items, Fish->fish



376
377
378
# File 'lib/avo/base_resource.rb', line 376

def model_key
  model_class.model_name.plural
end

#model_titleObject



221
222
223
224
225
# File 'lib/avo/base_resource.rb', line 221

def model_title
  return @model.send title if @model.present?

  name
end

#nameObject



233
234
235
236
237
238
239
# File 'lib/avo/base_resource.rb', line 233

def name
  return @name if @name.present?

  return I18n.t(translation_key, count: 1).capitalize if translation_key

  class_name_without_resource.titlecase
end


257
258
259
# File 'lib/avo/base_resource.rb', line 257

def navigation_label
  plural_name.humanize
end

#panelsObject



196
197
198
199
200
201
202
203
204
# File 'lib/avo/base_resource.rb', line 196

def panels
  [
    {
      name: default_panel_name,
      type: :fields,
      in_panel: true
    }
  ]
end

#plural_nameObject



245
246
247
248
249
# File 'lib/avo/base_resource.rb', line 245

def plural_name
  return I18n.t(translation_key, count: 2).capitalize if translation_key

  name.pluralize
end

#record_pathObject



384
385
386
# File 'lib/avo/base_resource.rb', line 384

def record_path
  resource_path(model: model, resource: self)
end

#records_pathObject



388
389
390
# File 'lib/avo/base_resource.rb', line 388

def records_path
  resources_path(resource: self)
end

#route_keyObject



368
369
370
# File 'lib/avo/base_resource.rb', line 368

def route_key
  model_class.model_name.route_key
end

#singular_model_keyObject



380
381
382
# File 'lib/avo/base_resource.rb', line 380

def singular_model_key
  model_class.model_name.singular
end

#singular_nameObject



241
242
243
# File 'lib/avo/base_resource.rb', line 241

def singular_name
  name
end

#translation_keyObject



227
228
229
230
231
# File 'lib/avo/base_resource.rb', line 227

def translation_key
  return "avo.resource_translations.#{class_name_without_resource.underscore}" if self.class.translation_enabled

  self.class.translation_key
end

#underscore_nameObject



251
252
253
254
255
# File 'lib/avo/base_resource.rb', line 251

def underscore_name
  return @name if @name.present?

  self.class.name.demodulize.underscore
end