Class: ApiMaker::BaseResource

Inherits:
Object
  • Object
show all
Defined in:
lib/api_maker/base_resource.rb

Constant Summary collapse

CRUD =
[:create, :create_events, :read, :update, :update_events, :destroy, :destroy_events].freeze
READ =
[:create_events, :destroy_events, :read, :update_events].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ability: nil, api_maker_args: {}, locals:, model:) ⇒ BaseResource

Returns a new instance of BaseResource.



108
109
110
111
112
113
# File 'lib/api_maker/base_resource.rb', line 108

def initialize(ability: nil, api_maker_args: {}, locals:, model:)
  @ability = ability
  @api_maker_args = api_maker_args
  @locals = locals || api_maker_args&.dig(:locals) || {}
  @model = model
end

Instance Attribute Details

#abilityObject (readonly)

Returns the value of attribute ability.



4
5
6
# File 'lib/api_maker/base_resource.rb', line 4

def ability
  @ability
end

#api_maker_argsObject (readonly)

Returns the value of attribute api_maker_args.



4
5
6
# File 'lib/api_maker/base_resource.rb', line 4

def api_maker_args
  @api_maker_args
end

#localsObject (readonly)

Returns the value of attribute locals.



4
5
6
# File 'lib/api_maker/base_resource.rb', line 4

def locals
  @locals
end

#modelObject (readonly)

Returns the value of attribute model.



4
5
6
# File 'lib/api_maker/base_resource.rb', line 4

def model
  @model
end

Class Method Details

._attributesObject



24
25
26
# File 'lib/api_maker/base_resource.rb', line 24

def self._attributes
  ApiMaker::MemoryStorage.current.storage_for(self, :attributes)
end

._attributes_with_string_keysObject



28
29
30
31
32
33
34
35
36
# File 'lib/api_maker/base_resource.rb', line 28

def self._attributes_with_string_keys
  @_attributes_with_string_keys ||= begin
    result = {}
    _attributes.each do |key, value|
      result[key.to_s] = value
    end
    result
  end
end

._relationshipsObject



78
79
80
# File 'lib/api_maker/base_resource.rb', line 78

def self._relationships
  ApiMaker::MemoryStorage.current.storage_for(self, :relationships)
end

.attribute(attribute_name, **args) ⇒ Object



11
12
13
14
15
16
# File 'lib/api_maker/base_resource.rb', line 11

def self.attribute(attribute_name, **args)
  # Automatically add a columns argument if the attribute name matches a column name on the models table
  args[:requires_columns] = [attribute_name] if !args.key?(:requires_columns) && column_exists_on_model?(model_class, attribute_name)

  ApiMaker::MemoryStorage.current.add(self, :attributes, attribute_name, args)
end

.attributes(*attributes, **args) ⇒ Object



18
19
20
21
22
# File 'lib/api_maker/base_resource.rb', line 18

def self.attributes(*attributes, **args)
  attributes.each do |attribute_name|
    attribute(attribute_name, args)
  end
end

.collection_commands(*list) ⇒ Object



38
39
40
41
42
# File 'lib/api_maker/base_resource.rb', line 38

def self.collection_commands(*list)
  list.each do |collection_command|
    ApiMaker::MemoryStorage.current.add(self, :collection_commands, collection_command)
  end
end

.collection_nameObject



82
83
84
# File 'lib/api_maker/base_resource.rb', line 82

def self.collection_name
  @collection_name ||= plural_name.underscore
end

.column_exists_on_model?(model_class, column_name) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
49
# File 'lib/api_maker/base_resource.rb', line 44

def self.column_exists_on_model?(model_class, column_name)
  model_class.column_names.include?(column_name.to_s)
rescue ActiveRecord::StatementInvalid
  # This happens if the table or column doesn't exist - like if we are running during a migration
  false
end

.default_selectObject



86
87
88
89
90
# File 'lib/api_maker/base_resource.rb', line 86

def self.default_select
  _attributes.select do |_attribute_name, args|
    !args.fetch(:args).key?(:selected_by_default) || args.fetch(:args).fetch(:selected_by_default)
  end
end

.member_commands(*list) ⇒ Object



51
52
53
54
55
# File 'lib/api_maker/base_resource.rb', line 51

def self.member_commands(*list)
  list.each do |member_command|
    ApiMaker::MemoryStorage.current.add(self, :member_commands, member_command)
  end
end

.model_classObject



63
64
65
66
# File 'lib/api_maker/base_resource.rb', line 63

def self.model_class
  # Use the name to constantize to avoid reloading issues with Rails
  model_class_name.constantize
end

.model_class=(klass) ⇒ Object



57
58
59
60
61
# File 'lib/api_maker/base_resource.rb', line 57

def self.model_class=(klass)
  # Set the name to avoid reloading issues with Rails
  @model_class_name ||= klass.name
  ApiMaker::MemoryStorage.current.model_class_for(resource: self, klass: klass)
end

.model_class_nameObject



68
69
70
# File 'lib/api_maker/base_resource.rb', line 68

def self.model_class_name
  @model_class_name ||= short_name
end

.plural_nameObject



92
93
94
# File 'lib/api_maker/base_resource.rb', line 92

def self.plural_name
  @plural_name ||= short_name.pluralize
end

.relationships(*relationships) ⇒ Object



72
73
74
75
76
# File 'lib/api_maker/base_resource.rb', line 72

def self.relationships(*relationships)
  relationships.each do |relationship|
    ApiMaker::MemoryStorage.current.add(self, :relationships, relationship)
  end
end

.require_nameObject



96
97
98
# File 'lib/api_maker/base_resource.rb', line 96

def self.require_name
  @require_name ||= collection_name.singularize
end

.short_nameObject



100
101
102
# File 'lib/api_maker/base_resource.rb', line 100

def self.short_name
  @short_name ||= name.match(/\AResources::(.+)Resource\Z/)[1]
end

.underscore_nameObject



104
105
106
# File 'lib/api_maker/base_resource.rb', line 104

def self.underscore_name
  @underscore_name ||= plural_name.underscore
end

Instance Method Details

#can_access_through(ability:, relationship:) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/api_maker/base_resource.rb', line 115

def can_access_through(ability:, relationship:)
  reflection = model_class.reflections.fetch(relationship.to_s)
  target_model_class = reflection.klass
  self.ability.load_abilities(target_model_class)
  relevant_rules = self.ability.__send__(:relevant_rules, ability, target_model_class)

  relevant_rules.each do |relevant_rule|
    if relevant_rule.conditions.empty?
      handle_empty_conditions(
        model_class: model_class,
        reflection: reflection,
        relationship: relationship,
        target_model_class: target_model_class
      )
    elsif relevant_rule.conditions.is_a?(Array)
      handle_array_condition_rule(
        ability: ability,
        model_class: model_class,
        reflection: reflection,
        relevant_rule: relevant_rule
      )
    else
      can ability, model_class, {
        reflection.name => relevant_rule.conditions
      }
    end
  end
end

#inspectObject



144
145
146
# File 'lib/api_maker/base_resource.rb', line 144

def inspect
  "#<#{self.class.name}:#{__id__}>"
end

#model_classObject



148
149
150
# File 'lib/api_maker/base_resource.rb', line 148

def model_class
  self.class.model_class
end