Class: Airrel::Relation

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/airrel/relation.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Relation

Returns a new instance of Relation.



9
10
11
12
13
14
15
16
17
# File 'lib/airrel/relation.rb', line 9

def initialize(klass)
  @klass = klass
  @where_clause = WhereClause.new
  @order_values = []
  @limit_value = nil
  @offset_value = nil
  @loaded = false
  @records = nil
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass.



7
8
9
# File 'lib/airrel/relation.rb', line 7

def klass
  @klass
end

#limit_valueObject (readonly)

Returns the value of attribute limit_value.



7
8
9
# File 'lib/airrel/relation.rb', line 7

def limit_value
  @limit_value
end

#offset_valueObject (readonly)

Returns the value of attribute offset_value.



7
8
9
# File 'lib/airrel/relation.rb', line 7

def offset_value
  @offset_value
end

#order_valuesObject (readonly)

Returns the value of attribute order_values.



7
8
9
# File 'lib/airrel/relation.rb', line 7

def order_values
  @order_values
end

#where_clauseObject (readonly)

Returns the value of attribute where_clause.



7
8
9
# File 'lib/airrel/relation.rb', line 7

def where_clause
  @where_clause
end

Instance Method Details

#allObject



95
# File 'lib/airrel/relation.rb', line 95

def all = spawn

#any?Boolean

OPTIMIZE: only load 1 record to check existence

Returns:

  • (Boolean)


136
# File 'lib/airrel/relation.rb', line 136

def any? = limit(1).load_records.any?

#countObject

airtable doesn't have a count API >:-/ we gotta paginate through EVERYTHING...



131
# File 'lib/airrel/relation.rb', line 131

def count = load_records.size

#each(&block) ⇒ Object



101
# File 'lib/airrel/relation.rb', line 101

def each(&block) = load_records.each(&block)

#empty?Boolean

Returns:

  • (Boolean)


133
# File 'lib/airrel/relation.rb', line 133

def empty? = !any?

#exists?Boolean

Returns:

  • (Boolean)


138
# File 'lib/airrel/relation.rb', line 138

def exists? = any?

#find(id) ⇒ Object



85
# File 'lib/airrel/relation.rb', line 85

def find(id) = klass.find(id)

#find_by(conditions) ⇒ Object



87
# File 'lib/airrel/relation.rb', line 87

def find_by(conditions) = where(conditions).first

#find_by!(conditions) ⇒ Object



89
90
91
92
93
# File 'lib/airrel/relation.rb', line 89

def find_by!(conditions)
  # Raise error class that will be defined by the consumer (norairrecord)
  error_class = defined?(Norairrecord::RecordNotFoundError) ? Norairrecord::RecordNotFoundError : StandardError
  find_by(conditions) || raise(error_class, "Record not found")
end

#find_each(batch_size: 100, &block) ⇒ Object

batch iteration for large result sets



104
105
106
107
108
# File 'lib/airrel/relation.rb', line 104

def find_each(batch_size: 100, &block)
  find_in_batches(batch_size: batch_size) do |batch|
    batch.each(&block)
  end
end

#find_in_batches(batch_size: 100) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/airrel/relation.rb', line 110

def find_in_batches(batch_size: 100)
  current_offset = 0

  loop do
    # create a new relation with limit and offset
    batch_relation = spawn
    batch_relation.instance_variable_set(:@limit_value, batch_size)
    batch_relation.instance_variable_set(:@offset_value, current_offset)

    batch = batch_relation.to_a
    break if batch.empty?

    yield batch

    break if batch.size < batch_size # last batch

    current_offset += batch_size
  end
end

#first(limit = nil) ⇒ Object

finder methods (execute queries)



58
59
60
61
62
63
64
65
66
# File 'lib/airrel/relation.rb', line 58

def first(limit = nil)
  if limit
    # explicitly set limit to avoid loading more than needed
    self.limit(limit).to_a
  else
    # only load 1 record
    self.limit(1).to_a.first
  end
end

#inspectObject

inspection



142
143
144
145
146
147
# File 'lib/airrel/relation.rb', line 142

def inspect
  entries = load_records.take(11).map!(&:inspect)
  entries[10] = "..." if entries.size == 11

  "#<#{self.class.name} [#{entries.join(", ")}]>"
end

#last(limit = nil) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/airrel/relation.rb', line 68

def last(limit = nil)
  # if no order specified, airtable returns oldest first by default
  # so we need to explicitly reverse or it's meaningless
  if @order_values.empty?
    raise ArgumentError, "last requires an order to be specified (use .order(:created_at) or similar)"
  end

  reversed = reverse_order
  if limit
    # only load what we need
    reversed.limit(limit).to_a.reverse
  else
    # only load 1 record
    reversed.limit(1).to_a.first
  end
end

#limit(value) ⇒ Object



35
# File 'lib/airrel/relation.rb', line 35

def limit(value) = spawn.limit!(value)

#limit!(value) ⇒ Object



37
38
39
40
# File 'lib/airrel/relation.rb', line 37

def limit!(value)
  @limit_value = value
  self
end

#loadObject

execution



155
156
157
158
# File 'lib/airrel/relation.rb', line 155

def load
  @records = exec_queries unless loaded?
  self
end

#loaded?Boolean

Returns:

  • (Boolean)


165
# File 'lib/airrel/relation.rb', line 165

def loaded? = @loaded

#offset(value) ⇒ Object



42
# File 'lib/airrel/relation.rb', line 42

def offset(value) = spawn.offset!(value)

#offset!(value) ⇒ Object



44
45
46
47
# File 'lib/airrel/relation.rb', line 44

def offset!(value)
  @offset_value = value
  self
end

#order(*args) ⇒ Object



28
# File 'lib/airrel/relation.rb', line 28

def order(*args) = spawn.order!(*args)

#order!(*args) ⇒ Object



30
31
32
33
# File 'lib/airrel/relation.rb', line 30

def order!(*args)
  @order_values += parse_order_args(args)
  self
end

#reloadObject



160
161
162
163
# File 'lib/airrel/relation.rb', line 160

def reload
  reset
  load
end

#reorder(*args) ⇒ Object



49
# File 'lib/airrel/relation.rb', line 49

def reorder(*args) = spawn.reorder!(*args)

#reorder!(*args) ⇒ Object



51
52
53
54
# File 'lib/airrel/relation.rb', line 51

def reorder!(*args)
  @order_values = parse_order_args(args)
  self
end

#resetObject



167
168
169
170
171
# File 'lib/airrel/relation.rb', line 167

def reset
  @loaded = false
  @records = nil
  self
end

#to_aObject Also known as: to_ary



97
# File 'lib/airrel/relation.rb', line 97

def to_a = load_records

#to_airtableObject



149
# File 'lib/airrel/relation.rb', line 149

def to_airtable = to_airtable_params

#to_sqlObject



151
# File 'lib/airrel/relation.rb', line 151

def to_sql = to_airtable_params.inspect

#where(conditions) ⇒ Object

chaining methods (return new relations)



21
# File 'lib/airrel/relation.rb', line 21

def where(conditions) = spawn.where!(conditions)

#where!(conditions) ⇒ Object



23
24
25
26
# File 'lib/airrel/relation.rb', line 23

def where!(conditions)
  @where_clause = @where_clause.merge(conditions)
  self
end

#without_paginationObject

disable automatic pagination for better control



174
175
176
177
# File 'lib/airrel/relation.rb', line 174

def without_pagination
  @paginate = false
  self
end