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.


62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/og/collection.rb', line 62

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


269
270
271
272
273
274
275
276
# File 'lib/og/collection.rb', line 269

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?


54
55
56
# File 'lib/og/collection.rb', line 54

def building
  @building
end

#building_membersObject

When the collection is in building mode or the owner object is unsaved, added members are accumulated in the building_memebers array. These relations are serialized when the owner object is saved (or when save_building_members is explicitly called).


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

def building_members
  @building_members
end

#count_procObject

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


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

def count_proc
  @count_proc
end

#find_optionsObject

The default find options.


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

def find_options
  @find_options
end

#find_procObject

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


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

def find_proc
  @find_proc
end

#insert_procObject

A method used to add insert objects in the collection.


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

def insert_proc
  @insert_proc
end

#loadedObject

Is the collection loaded?


58
59
60
# File 'lib/og/collection.rb', line 58

def loaded
  @loaded
end

#member_classObject

The class of the members of this collection.


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

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.


36
37
38
# File 'lib/og/collection.rb', line 36

def remove_proc
  @remove_proc
end

Instance Method Details

#[](idx) ⇒ Object

Defined to avoid the method missing overhead.


118
119
120
121
# File 'lib/og/collection.rb', line 118

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

#delete(*objects) ⇒ Object

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


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

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.


215
216
217
218
219
220
# File 'lib/og/collection.rb', line 215

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.


187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/og/collection.rb', line 187

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.


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

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

#find(options = {}) ⇒ Object

Allows to perform a scoped query.


235
236
237
238
239
240
241
# File 'lib/og/collection.rb', line 235

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

#find_one(options = {}) ⇒ Object

Find one object.


245
246
247
# File 'lib/og/collection.rb', line 245

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

#load_membersObject

Load the members of the collection.


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

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.

If the collection is in build mode or the object is unsaved, the member is accumulated in a buffer. All accumulated members relations are saved when the object is saved.


132
133
134
135
136
137
138
139
140
141
# File 'lib/og/collection.rb', line 132

def push(obj, options = nil)
  remove(obj) if members.include?(obj)
  @members << obj
  unless @building or owner.unsaved?
    @owner.send(@insert_proc, obj, options)
  else
    (@building_members ||= []) << obj
    @owner.instance_variable_set '@pending_building_collections', true
  end
end

#reload(options = {}) ⇒ Object

Reload the collection.


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

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! ++


151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/og/collection.rb', line 151

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.


203
204
205
206
207
208
209
# File 'lib/og/collection.rb', line 203

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

#save_building_members(options = nil) ⇒ Object

In building mode, relations for this collection are accumulated in @building_relations. These relations are saved my calling this method.


253
254
255
256
257
258
259
260
# File 'lib/og/collection.rb', line 253

def save_building_members(options = nil)
  return unless @building_members
  
  for obj in @building_members
    @owner.send(@insert_proc, obj, options)
  end
  @building_members = nil
end

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

Return the size of a collection.


224
225
226
227
228
229
230
# File 'lib/og/collection.rb', line 224

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.


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

def to_ary
  load_members
  @members
end

#unloadObject

Unload the members (clear the cache).


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

def unload
  @members.clear
  @loaded = false
end