Class: Og::Collection

Inherits:
Object
  • Object
show all
Defined in:
lib/og/collection.rb

Overview

An ‘active’ collection that reflects a relation. A collection stores entitities that participate in a relation.

Direct Known Subclasses

HasManyCollection, JoinsManyCollection

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner = nil, member_class = nil, insert_proc = nil, remove_proc = nil, find_proc = nil, count_proc = nil, find_options = {}) ⇒ Collection

Initialize the collection.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/og/collection.rb', line 54

def initialize(owner = nil, member_class = nil, insert_proc = nil, 
    remove_proc = nil, find_proc = nil, 
    count_proc = nil, find_options = {})
  @owner = owner
  @member_class = member_class
  @insert_proc = insert_proc
  @remove_proc = remove_proc
  @find_proc = find_proc
  @count_proc = count_proc
  @find_options = find_options
  @members = []
  @loaded = false
  @building = false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object

Try to execute an accumulator or else redirect all other methods to the members array.

An example of the accumulator:

foo_foobars = foo1.bars.foobars



238
239
240
241
242
243
244
245
# File 'lib/og/collection.rb', line 238

def method_missing(symbol, *args, &block)
  load_members
  if @member_class.instance_methods.include? symbol.to_s
    @members.inject([]) { |a, x| a << x.send(symbol) }.flatten
  else
    @members.send(symbol, *args, &block)
  end
end

Instance Attribute Details

#buildingObject

Is the collection in build mode?



46
47
48
# File 'lib/og/collection.rb', line 46

def building
  @building
end

#count_procObject

A method used to count the objects that belong to the collection.



38
39
40
# File 'lib/og/collection.rb', line 38

def count_proc
  @count_proc
end

#find_optionsObject

The default find options.



42
43
44
# File 'lib/og/collection.rb', line 42

def find_options
  @find_options
end

#find_procObject

A method used to find the objects that belong to the collection.



33
34
35
# File 'lib/og/collection.rb', line 33

def find_proc
  @find_proc
end

#insert_procObject

A method used to add insert objects in the collection.



24
25
26
# File 'lib/og/collection.rb', line 24

def insert_proc
  @insert_proc
end

#loadedObject

Is the collection loaded?



50
51
52
# File 'lib/og/collection.rb', line 50

def loaded
  @loaded
end

#member_classObject

The class of the members of this collection.



20
21
22
# File 'lib/og/collection.rb', line 20

def member_class
  @member_class
end

#membersObject

The members of this collection. Keeps the objects that belong to this collection.



16
17
18
# File 'lib/og/collection.rb', line 16

def members
  @members
end

#ownerObject

The owner of this collection.



11
12
13
# File 'lib/og/collection.rb', line 11

def owner
  @owner
end

#remove_procObject

A method used to remove objects from the collection.



28
29
30
# File 'lib/og/collection.rb', line 28

def remove_proc
  @remove_proc
end

Instance Method Details

#[](idx) ⇒ Object

Defined to avoid the method missing overhead.



110
111
112
113
# File 'lib/og/collection.rb', line 110

def [](idx)
  load_members
  @members[idx]
end

#delete(*objects) ⇒ Object

Delete a member from the collection AND the store. – TODO: add delete by oid! ++



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/og/collection.rb', line 154

def delete(*objects)
  objects = objects.flatten

  objects.reject! { |obj| @members.delete(obj) if obj.unsaved? }
  return if objects.empty?

  @owner.transaction do
    objects.each do |obj| 
      obj.delete
      @members.delete(obj) 
    end
  end
end

#delete_allObject

Delete all members of the collection. Also delete from the store.



199
200
201
202
203
204
# File 'lib/og/collection.rb', line 199

def delete_all
  @owner.transaction do
    self.each { |obj| obj.delete }
  end
  @members.clear
end

#delete_if(&block) ⇒ Object

Delete a member from the collection AND the store, if the condition block evaluates to true.



171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/og/collection.rb', line 171

def delete_if(&block)
  objects = @members.select(&block)

  objects.reject! { |obj| @members.delete(obj) if obj.unsaved? }
  return if objects.empty?

  @owner.transaction do
    objects.each do |obj|
      obj.delete
      @members.delete(obj)
    end
  end
end

#each(&block) ⇒ Object

Defined to avoid the method missing overhead.



103
104
105
106
# File 'lib/og/collection.rb', line 103

def each(&block)
  load_members
  @members.each(&block)
end

#find(options = {}) ⇒ Object

Allows to perform a scoped query.



219
220
221
222
223
# File 'lib/og/collection.rb', line 219

def find(options = {})
  @member_class.with_scope(options) do
    return @owner.send(@find_proc, @find_options)    
  end
end

#find_one(options = {}) ⇒ Object

Find one object.



227
228
229
# File 'lib/og/collection.rb', line 227

def find_one(options = {})
  find(options).first
end

#load_membersObject

Load the members of the collection.



71
72
73
74
75
76
77
# File 'lib/og/collection.rb', line 71

def load_members
  unless @loaded or @owner.unsaved?
    @members = @owner.send(@find_proc, @find_options)
    @loaded = true
  end
  @members
end

#push(obj, options = nil) ⇒ Object Also known as: <<, add

Add a new member to the collection. this method will overwrite any objects already existing in the collection



119
120
121
122
123
124
125
# File 'lib/og/collection.rb', line 119

def push(obj, options = nil)
  remove(obj) if members.include?(obj)
  @members.push(obj)
  unless @building or owner.unsaved?
    @owner.send(@insert_proc, obj, options)
  end
end

#reload(options = {}) ⇒ Object

Reload the collection.



81
82
83
84
85
# File 'lib/og/collection.rb', line 81

def reload(options = {})
  # gmosx, NOOO: this was a bug! it corrupts the default options.
  #  @find_options = options
  @members = @owner.send(@find_proc, options)
end

#remove(*objects) ⇒ Object

Remove a member from the collection, the actual object is not deleted. – TODO: add remove by oid! ++



135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/og/collection.rb', line 135

def remove(*objects)
  objects = objects.flatten

  objects.reject! { |obj| @members.delete(obj) if obj.unsaved? }
  return if objects.empty?

  @owner.transaction do
    objects.each do |obj| 
      @owner.send(@remove_proc, obj)
      @members.delete(obj) 
    end
  end
end

#remove_allObject Also known as: clear

Remove all members from the collection.



187
188
189
190
191
192
193
# File 'lib/og/collection.rb', line 187

def remove_all
  @owner.transaction do
    self.each { |obj| @owner.send(@remove_proc, obj) }
  end
  @members.clear
  @loaded = false # gmosx: IS this needed?
end

#size(reload = false) ⇒ Object Also known as: count

Return the size of a collection.



208
209
210
211
212
213
214
# File 'lib/og/collection.rb', line 208

def size(reload = false)
  if @loaded and !reload
    return @members.size
  else
    return @owner.send(@count_proc)
  end
end

#to_aryObject

Convert the collection to an array.



96
97
98
99
# File 'lib/og/collection.rb', line 96

def to_ary
  load_members
  @members
end

#unloadObject

Unload the members (clear the cache).



89
90
91
92
# File 'lib/og/collection.rb', line 89

def unload
  @members.clear
  @loaded = false
end