Class: ReactiveRecord::Collection
- Inherits:
-
Object
- Object
- ReactiveRecord::Collection
show all
- Defined in:
- lib/reactive_record/active_record/reactive_record/collection.rb
Instance Method Summary
collapse
Constructor Details
#initialize(target_klass, owner = nil, association = nil, *vector) ⇒ Collection
Returns a new instance of Collection.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 5
def initialize(target_klass, owner = nil, association = nil, *vector)
@owner = owner @association = association
@target_klass = target_klass
if owner and !owner.id and vector.length <= 1
@collection = []
elsif vector.length > 0
@vector = vector
elsif owner
@vector = owner.backing_record.vector + [association.attribute]
else
@vector = [target_klass]
end
@scopes = {}
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
174
175
176
177
178
179
180
181
182
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 174
def method_missing(method, *args, &block)
if [].respond_to? method
all.send(method, *args, &block)
elsif @target_klass.respond_to?(method) or (args.count == 1 && method =~ /^find_by_/)
apply_scope(method, *args)
else
super
end
end
|
Instance Method Details
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 96
def <<(item)
return delete(item) if item.destroyed? backing_record = item.backing_record
all << item unless all.include? item if backing_record and @owner and @association and inverse_of = @association.inverse_of and item.attributes[inverse_of] != @owner
current_association = item.attributes[inverse_of]
backing_record.virgin = false unless backing_record.data_loading?
backing_record.update_attribute(inverse_of, @owner)
current_association.attributes[@association.attribute].delete(item) if current_association and current_association.attributes[@association.attribute]
@owner.backing_record.update_attribute(@association.attribute) end
if item.id and @dummy_record
@dummy_record.id = item.id
@collection.delete(@dummy_record)
@dummy_record = @collection.detect { |r| r.backing_record.vector.last =~ /^\*[0-9]+$/ }
@dummy_collection = nil
end
notify_of_change self
end
|
#==(other_collection) ⇒ Object
58
59
60
61
62
63
64
65
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 58
def ==(other_collection)
observed
return !@collection unless other_collection.is_a? Collection
other_collection.observed
my_collection = (@collection || []).select { |target| target != @dummy_record }
other_collection = (other_collection ? (other_collection.collection || []) : []).select { |target| target != other_collection.dummy_record }
my_collection == other_collection
end
|
#[](index) ⇒ Object
46
47
48
49
50
51
52
53
54
55
56
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 46
def [](index)
observed
if (@collection || all).length <= index and @dummy_collection
(@collection.length..index).each do |i|
new_dummy_record = ReactiveRecord::Base.new_from_vector(@target_klass, nil, *@vector, "*#{i}")
new_dummy_record.backing_record.attributes[@association.inverse_of] = @owner if @association and @association.inverse_of
@collection << new_dummy_record
end
end
@collection[index]
end
|
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 29
def all
observed
@dummy_collection.notify if @dummy_collection
unless @collection
@collection = []
if ids = ReactiveRecord::Base.fetch_from_db([*@vector, "*all"])
ids.each do |id|
@collection << @target_klass.find_by(@target_klass.primary_key => id)
end
else
@dummy_collection = ReactiveRecord::Base.load_from_db(nil, *@vector, "*all")
@dummy_record = self[0]
end
end
@collection
end
|
#apply_scope(scope, *args) ⇒ Object
67
68
69
70
71
72
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 67
def apply_scope(scope, *args)
scope = [scope, *args] if args.count > 0
@scopes[scope] ||= Collection.new(@target_klass, @owner, @association, *@vector, [scope])
end
|
#count ⇒ Object
Also known as:
length
74
75
76
77
78
79
80
81
82
83
84
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 74
def count
observed
if @collection
@collection.count
elsif @count ||= ReactiveRecord::Base.fetch_from_db([*@vector, "*count"])
@count
else
ReactiveRecord::Base.load_from_db(nil, *@vector, "*count")
@count = 1
end
end
|
#delete(item) ⇒ Object
153
154
155
156
157
158
159
160
161
162
163
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 153
def delete(item)
notify_of_change(if @owner and @association and inverse_of = @association.inverse_of
if backing_record = item.backing_record and backing_record.attributes[inverse_of] == @owner
backing_record.update_attribute(inverse_of, nil)
end
all.delete(item).tap { @owner.backing_record.update_attribute(@association.attribute) } else
all.delete(item)
end)
end
|
#dup_for_sync ⇒ Object
21
22
23
24
25
26
27
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 21
def dup_for_sync
self.dup.instance_eval do
@collection = @collection.dup if @collection
@scopes = @scopes.dup
self
end
end
|
#empty? ⇒ Boolean
should be handled by method missing below, but opal-rspec does not deal well with method missing, so to test…
170
171
172
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 170
def empty? all.empty?
end
|
92
93
94
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 92
def klass
@target_klass
end
|
#loading? ⇒ Boolean
165
166
167
168
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 165
def loading?
all @dummy_collection.loading?
end
|
#proxy_association ⇒ Object
88
89
90
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 88
def proxy_association
@association || self end
|
#replace(new_array) ⇒ Object
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# File 'lib/reactive_record/active_record/reactive_record/collection.rb', line 126
def replace(new_array)
if @dummy_collection
@dummy_collection.notify
array = new_array.is_a?(Collection) ? new_array.collection : new_array
@collection.each_with_index do |r, i|
r.id = new_array[i].id if array[i] and array[i].id and !r.new? and r.backing_record.vector.last =~ /^\*[0-9]+$/
end
end
@collection.dup.each { |item| delete(item) } if @collection @collection = []
if new_array.is_a? Collection
@dummy_collection = new_array.dummy_collection
@dummy_record = new_array.dummy_record
new_array.collection.each { |item| self << item } if new_array.collection
else
@dummy_collection = @dummy_record = nil
new_array.each { |item| self << item }
end
notify_of_change new_array
end
|