Class: ActivePostgrest::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/active_postgrest/base.rb

Constant Summary collapse

POSTGRES_TYPE_CAST =
{
  'date' => :date,
  'timestamp' => :datetime,
  'timestamp with time zone' => :datetime,
  'timestamp without time zone' => :datetime,
  'time' => :time,
  'time with time zone' => :time,
  'time without time zone' => :time,
  'numeric' => :decimal,
  'decimal' => :decimal,
  'real' => :decimal,
  'double precision' => :decimal
}.freeze

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ Base

Returns a new instance of Base.



174
175
176
177
178
179
# File 'lib/active_postgrest/base.rb', line 174

def initialize(attrs = {})
  types = self.class.attribute_types
  @attributes = attrs.to_h.transform_keys(&:to_s).to_h do |k, v|
    [k, types[k] ? cast_attribute(v, types[k]) : v]
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name) ⇒ Object



190
191
192
193
194
195
# File 'lib/active_postgrest/base.rb', line 190

def method_missing(name, *)
  key = name.to_s
  return @attributes[key] if @attributes.key?(key)

  super
end

Class Attribute Details

.schema_nameObject



30
31
32
# File 'lib/active_postgrest/base.rb', line 30

def self.schema_name
  @schema_name || (superclass.schema_name if superclass.respond_to?(:schema_name))
end

.table_nameObject



22
23
24
# File 'lib/active_postgrest/base.rb', line 22

def self.table_name
  @table_name ||= name.demodulize.underscore.pluralize
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



182
183
184
# File 'lib/active_postgrest/base.rb', line 182

def attributes
  @attributes
end

Class Method Details

.allObject



137
# File 'lib/active_postgrest/base.rb', line 137

def self.all                   = relation

.and_where(conditions) ⇒ Object



145
# File 'lib/active_postgrest/base.rb', line 145

def self.and_where(conditions) = relation.and_where(conditions)

.anonymousObject



139
# File 'lib/active_postgrest/base.rb', line 139

def self.anonymous             = relation.anonymous

.any?Boolean

Returns:

  • (Boolean)


169
# File 'lib/active_postgrest/base.rb', line 169

def self.any?         = relation.any?

.attribute(name, type) ⇒ Object



55
56
57
58
# File 'lib/active_postgrest/base.rb', line 55

def self.attribute(name, type)
  @attribute_types ||= {}
  @attribute_types[name.to_s] = type
end

.attribute_typesObject



60
61
62
# File 'lib/active_postgrest/base.rb', line 60

def self.attribute_types
  @attribute_types || {}
end

.attributesObject



68
69
70
# File 'lib/active_postgrest/base.rb', line 68

def self.attributes
  schema['properties']&.transform_values { _1['format'] } || {}
end

.belongs_to(name, class_name: nil, foreign_key: nil) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/active_postgrest/base.rb', line 72

def self.belongs_to(name, class_name: nil, foreign_key: nil)
  assoc   = name.to_s
  klass   = class_name&.to_s || assoc.camelize
  table   = klass.underscore.pluralize
  fk      = foreign_key&.to_s
  aliased = fk || (klass.underscore != assoc)
  key     = aliased ? assoc : table

  define_method(assoc) do
    val = @attributes[key]
    return nil if val.nil? || (val.is_a?(Array) && val.empty?)

    klass.constantize.new(val.is_a?(Array) ? val.first : val)
  end

  define_singleton_method(:"with_#{assoc}") do |fields: []|
    if aliased
      joins(table.to_sym, as: assoc.to_sym, foreign_key: fk&.to_sym, select: fields)
    else
      joins(table.to_sym, select: fields)
    end
  end
end

.connectionObject



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

def self.connection
  @connection ||
    if superclass.respond_to?(:connection)
      superclass.connection
    else
      ActivePostgrest::Client.new
    end
end

.count(mode = :exact) ⇒ Object



168
# File 'lib/active_postgrest/base.rb', line 168

def self.count(mode = :exact) = relation.count(mode)

.embedObject



151
# File 'lib/active_postgrest/base.rb', line 151

def self.embed(...)            = relation.embed(...)

.establish_connection(url: ENV.fetch('POSTGREST_URL'), jwt_token: nil) ⇒ Object



42
43
44
# File 'lib/active_postgrest/base.rb', line 42

def self.establish_connection(url: ENV.fetch('POSTGREST_URL'), jwt_token: nil)
  @connection = ActivePostgrest::Client.new(url, jwt_token)
end

.exists?(filters = {}) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
# File 'lib/active_postgrest/base.rb', line 162

def self.exists?(filters = {})
  filters.empty? ? relation.any? : relation.where(filters).any?
end

.find(id) ⇒ Object



157
# File 'lib/active_postgrest/base.rb', line 157

def self.find(id)             = relation.where(id: id).first

.find!(id) ⇒ Object



158
# File 'lib/active_postgrest/base.rb', line 158

def self.find!(id)            = find(id) || raise(ActivePostgrest::RecordNotFound.new(self, id))

.find_by(filters) ⇒ Object



159
# File 'lib/active_postgrest/base.rb', line 159

def self.find_by(filters)     = relation.where(filters).first

.find_by!(filters) ⇒ Object



160
# File 'lib/active_postgrest/base.rb', line 160

def self.find_by!(filters)    = find_by(filters) || raise(ActivePostgrest::RecordNotFound.new(self, filters))

.first(n = nil) ⇒ Object



155
# File 'lib/active_postgrest/base.rb', line 155

def self.first(n = nil)       = n ? relation.limit(n).to_a : relation.first

.has_many(name, class_name: nil) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/active_postgrest/base.rb', line 112

def self.has_many(name, class_name: nil)
  assoc = name.to_s
  klass = class_name&.to_s || assoc.singularize.camelize

  define_method(assoc) do
    val = @attributes[assoc]
    return [] if val.nil?

    Array(val).map { klass.constantize.new(_1) }
  end

  define_singleton_method(:"with_#{assoc}") do |fields: []|
    embed(assoc.to_sym, fields: fields)
  end
end

.has_one(name, class_name: nil) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/active_postgrest/base.rb', line 96

def self.has_one(name, class_name: nil)
  assoc = name.to_s
  klass = class_name&.to_s || assoc.camelize

  define_method(assoc) do
    val = @attributes[assoc]
    return nil if val.nil? || (val.is_a?(Array) && val.empty?)

    klass.constantize.new(val.is_a?(Array) ? val.first : val)
  end

  define_singleton_method(:"with_#{assoc}") do |fields: []|
    embed(assoc.to_sym, fields: fields)
  end
end

.joinsObject



150
# File 'lib/active_postgrest/base.rb', line 150

def self.joins(...)            = relation.joins(...)

.last(n = nil) ⇒ Object



156
# File 'lib/active_postgrest/base.rb', line 156

def self.last(n = nil)        = n ? relation.order(primary_key, :desc).limit(n).to_a.reverse : relation.last

.limit(n) ⇒ Object



148
# File 'lib/active_postgrest/base.rb', line 148

def self.limit(n)              = relation.limit(n)

.many?Boolean

Returns:

  • (Boolean)


172
# File 'lib/active_postgrest/base.rb', line 172

def self.many?        = relation.many?

.noneObject



138
# File 'lib/active_postgrest/base.rb', line 138

def self.none                  = relation.none

.none?Boolean

Returns:

  • (Boolean)


170
# File 'lib/active_postgrest/base.rb', line 170

def self.none?        = relation.none?

.not_where(filters) ⇒ Object



143
# File 'lib/active_postgrest/base.rb', line 143

def self.not_where(filters)    = relation.not_where(filters)

.offset(n) ⇒ Object



149
# File 'lib/active_postgrest/base.rb', line 149

def self.offset(n)             = relation.offset(n)

.one?Boolean

Returns:

  • (Boolean)


171
# File 'lib/active_postgrest/base.rb', line 171

def self.one?         = relation.one?

.or_where(conditions) ⇒ Object



144
# File 'lib/active_postgrest/base.rb', line 144

def self.or_where(conditions)  = relation.or_where(conditions)

.orderObject



146
# File 'lib/active_postgrest/base.rb', line 146

def self.order(...)            = relation.order(...)

.pick(*cols) ⇒ Object



167
# File 'lib/active_postgrest/base.rb', line 167

def self.pick(*cols)  = relation.pick(*cols)

.pluck(*cols) ⇒ Object



166
# File 'lib/active_postgrest/base.rb', line 166

def self.pluck(*cols) = relation.pluck(*cols)

.primary_keyObject



34
35
36
# File 'lib/active_postgrest/base.rb', line 34

def self.primary_key
  @primary_key ||= 'id'
end

.primary_key=(key) ⇒ Object



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

def self.primary_key=(key)
  @primary_key = key.to_s
end

.relationObject



132
133
134
135
# File 'lib/active_postgrest/base.rb', line 132

def self.relation
  rel = ActivePostgrest::Relation.new(table_name, connection, self)
  schema_name ? rel.with_schema(schema_name) : rel
end

.reorderObject



147
# File 'lib/active_postgrest/base.rb', line 147

def self.reorder(...)          = relation.reorder(...)

.schemaObject



64
65
66
# File 'lib/active_postgrest/base.rb', line 64

def self.schema
  connection.table_schema(table_name)
end

.scope(name, body) ⇒ Object



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

def self.scope(name, body)
  define_singleton_method(name) { |*args, **kwargs| body.call(*args, **kwargs) }
end

.selectObject



152
# File 'lib/active_postgrest/base.rb', line 152

def self.select(...)           = relation.select(...)

.spreadObject



153
# File 'lib/active_postgrest/base.rb', line 153

def self.spread(...)           = relation.spread(...)

.where(filters = nil) ⇒ Object



142
# File 'lib/active_postgrest/base.rb', line 142

def self.where(filters = nil)  = relation.where(filters)

.with_schema(name) ⇒ Object



141
# File 'lib/active_postgrest/base.rb', line 141

def self.with_schema(name)     = relation.with_schema(name)

.with_token(jwt) ⇒ Object



140
# File 'lib/active_postgrest/base.rb', line 140

def self.with_token(jwt)       = relation.with_token(jwt)

Instance Method Details

#[](key) ⇒ Object



181
# File 'lib/active_postgrest/base.rb', line 181

def [](key) = @attributes[key.to_s]

#inspectObject



186
187
188
# File 'lib/active_postgrest/base.rb', line 186

def inspect
  "#<#{self.class.name} #{@attributes.map { "#{_1}: #{_2.inspect}" }.join(', ')}>"
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/active_postgrest/base.rb', line 197

def respond_to_missing?(name, include_private = false)
  @attributes.key?(name.to_s) || super
end

#to_hObject



184
# File 'lib/active_postgrest/base.rb', line 184

def to_h = @attributes