Class: ActiveHash::Relation

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

Defined Under Namespace

Classes: Condition, Conditions, WhereChain

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, all_records, conditions = nil, order_values = nil) ⇒ Relation

Returns a new instance of Relation.



12
13
14
15
16
17
# File 'lib/active_hash/relation.rb', line 12

def initialize(klass, all_records, conditions = nil, order_values = nil)
  self.klass = klass
  self.all_records = all_records
  self.conditions = Conditions.wrap(conditions || [])
  self.order_values = order_values || []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object



166
167
168
169
170
# File 'lib/active_hash/relation.rb', line 166

def method_missing(method_name, *args)
  return super unless klass.scopes&.key?(method_name)

  instance_exec(*args, &klass.scopes[method_name])
end

Instance Attribute Details

#all_recordsObject

Returns the value of attribute all_records.



10
11
12
# File 'lib/active_hash/relation.rb', line 10

def all_records
  @all_records
end

#conditionsObject

Returns the value of attribute conditions.



10
11
12
# File 'lib/active_hash/relation.rb', line 10

def conditions
  @conditions
end

#klassObject

Returns the value of attribute klass.



10
11
12
# File 'lib/active_hash/relation.rb', line 10

def klass
  @klass
end

#order_valuesObject

Returns the value of attribute order_values.



10
11
12
# File 'lib/active_hash/relation.rb', line 10

def order_values
  @order_values
end

Instance Method Details

#all(options = {}) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/active_hash/relation.rb', line 95

def all(options = {})
  if options.key?(:conditions)
    where(options[:conditions])
  else
    where({})
  end
end

#countObject



137
138
139
# File 'lib/active_hash/relation.rb', line 137

def count
  length
end

#find(id = nil, *args, &block) ⇒ Object



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

def find(id = nil, *args, &block)
  case id
    when :all
      all
    when :first
      all(*args).first
    when Array
      id.map { |i| find(i) }
    when nil
      raise RecordNotFound.new("Couldn't find #{klass.name} without an ID", klass.name, "id") unless block_given?
      records.find(&block) # delegate to Enumerable#find if a block is given
    else
      find_by_id(id) || begin
        raise RecordNotFound.new("Couldn't find #{klass.name} with ID=#{id}", klass.name, "id", id)
      end
  end
end

#find_by(options) ⇒ Object



103
104
105
# File 'lib/active_hash/relation.rb', line 103

def find_by(options)
  where(options).first
end

#find_by!(options) ⇒ Object



107
108
109
# File 'lib/active_hash/relation.rb', line 107

def find_by!(options)
  find_by(options) || (raise RecordNotFound.new("Couldn't find #{klass.name}", klass.name))
end

#find_by_id(id) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/active_hash/relation.rb', line 129

def find_by_id(id)
  index = klass.send(:record_index)[id.to_s] # TODO: Make index in Base publicly readable instead of using send?
  return unless index

  record = all_records[index]
  record if conditions.matches?(record)
end

#idsObject



154
155
156
# File 'lib/active_hash/relation.rb', line 154

def ids
  pluck(:id)
end

#invert_whereObject



55
56
57
# File 'lib/active_hash/relation.rb', line 55

def invert_where
  spawn.invert_where!
end

#invert_where!Object



59
60
61
62
# File 'lib/active_hash/relation.rb', line 59

def invert_where!
  conditions.map(&:invert!)
  self
end

#order(*options) ⇒ Object



42
43
44
# File 'lib/active_hash/relation.rb', line 42

def order(*options)
  spawn.order!(*options)
end

#order!(*options) ⇒ Object



68
69
70
71
72
# File 'lib/active_hash/relation.rb', line 68

def order!(*options)
  check_if_method_has_arguments!(:order, options)
  self.order_values += preprocess_order_args(options)
  self
end

#pick(*column_names) ⇒ Object



158
159
160
# File 'lib/active_hash/relation.rb', line 158

def pick(*column_names)
  pluck(*column_names).first
end

#pluck(*column_names) ⇒ Object



145
146
147
148
149
150
151
152
# File 'lib/active_hash/relation.rb', line 145

def pluck(*column_names)
  if column_names.length == 1
    column_name = column_names.first
    all.map { |record| record.public_send(column_name) }
  else
    all.map { |record| column_names.map { |column_name| record.public_send(column_name) } }
  end
end

#pretty_print(pp) ⇒ Object



25
26
27
# File 'lib/active_hash/relation.rb', line 25

def pretty_print(pp)
  pp.pp(entries.to_ary)
end

#recordsObject



83
84
85
86
87
88
# File 'lib/active_hash/relation.rb', line 83

def records
  @records ||= begin
    filtered_records = apply_conditions(all_records, conditions)
    ordered_records = apply_order_values(filtered_records, order_values) # rubocop:disable Lint/UselessAssignment
  end
end

#reloadObject



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

def reload
  @records = nil # Reset records
  self
end

#reorder(*options) ⇒ Object



46
47
48
# File 'lib/active_hash/relation.rb', line 46

def reorder(*options)
  spawn.reorder!(*options)
end

#reorder!(*options) ⇒ Object



74
75
76
77
78
79
80
81
# File 'lib/active_hash/relation.rb', line 74

def reorder!(*options)
  check_if_method_has_arguments!(:order, options)

  self.order_values = preprocess_order_args(options)
  @records = apply_order_values(records, order_values)

  self
end

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

Returns:

  • (Boolean)


172
173
174
# File 'lib/active_hash/relation.rb', line 172

def respond_to_missing?(method_name, include_private = false)
  klass.scopes&.key?(method_name) || super
end

#sizeObject



141
142
143
# File 'lib/active_hash/relation.rb', line 141

def size
  length
end

#spawnObject



64
65
66
# File 'lib/active_hash/relation.rb', line 64

def spawn
  self.class.new(klass, all_records, conditions, order_values)
end

#to_aryObject



162
163
164
# File 'lib/active_hash/relation.rb', line 162

def to_ary
  records.dup
end

#where(conditions_hash = :chain) ⇒ Object



19
20
21
22
23
# File 'lib/active_hash/relation.rb', line 19

def where(conditions_hash = :chain)
  return WhereChain.new(self) if conditions_hash == :chain

  spawn.where!(conditions_hash)
end

#where!(conditions_hash, inverted = false) ⇒ Object



50
51
52
53
# File 'lib/active_hash/relation.rb', line 50

def where!(conditions_hash, inverted = false)
  self.conditions << Condition.new(conditions_hash)
  self
end