og 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ProjectInfo +2 -2
- data/README +1 -1
- data/doc/RELEASES +34 -0
- data/lib/glue/cacheable.rb +3 -1
- data/lib/glue/hierarchical.rb +3 -3
- data/lib/glue/orderable.rb +1 -1
- data/lib/glue/taggable.rb +71 -21
- data/lib/glue/timestamped.rb +2 -2
- data/lib/og.rb +16 -3
- data/lib/og/entity.rb +58 -10
- data/lib/og/ez/clause.rb +2 -1
- data/lib/og/manager.rb +38 -7
- data/lib/og/relation/joins_many.rb +1 -1
- data/lib/og/store/mysql.rb +2 -18
- data/lib/og/store/psql.rb +2 -1
- data/lib/og/store/sql.rb +79 -26
- data/lib/og/test/assertions.rb +1 -1
- data/lib/og/test/testcase.rb +3 -3
- data/test/glue/tc_revisable.rb +1 -1
- data/test/og/mixin/tc_hierarchical.rb +2 -0
- data/test/og/mixin/tc_orderable.rb +2 -3
- data/test/og/mixin/tc_taggable.rb +8 -11
- data/test/og/mixin/tc_timestamped.rb +1 -1
- data/test/og/store/tc_sti.rb +53 -0
- data/test/og/tc_aggregations_calculations.rb +44 -0
- data/test/og/tc_cacheable.rb +164 -29
- data/test/og/tc_inheritance.rb +4 -1
- data/test/og/tc_multi_validations.rb +1 -0
- data/test/og/tc_override.rb +6 -0
- metadata +11 -10
- data/lib/og/store/alpha/kirby.rb +0 -284
data/ProjectInfo
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
TITLE : &title Og
|
4
4
|
NAME : &pkg og
|
5
|
-
VERSION : '0.
|
5
|
+
VERSION : '0.29.0'
|
6
6
|
STATUS : beta
|
7
7
|
|
8
8
|
AUTHOR : George Moschovitis
|
@@ -17,7 +17,7 @@ DESCRIPTION: >
|
|
17
17
|
KirbyBase, Filesystem and more.
|
18
18
|
|
19
19
|
DEPENDENCIES:
|
20
|
-
- [ glue, '= 0.
|
20
|
+
- [ glue, '= 0.29.0' ]
|
21
21
|
|
22
22
|
DISTRIBUTE: [ gem, tgz, zip ]
|
23
23
|
|
data/README
CHANGED
data/doc/RELEASES
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
== Version 0.29.0
|
2
|
+
|
3
|
+
A bold step towards maturity. Great care was taken to
|
4
|
+
fix reported bugs and fine tune many aspects of Og.
|
5
|
+
As always some great new features where added. Special thanks fly
|
6
|
+
to Jonas Pfenniger, Bryan Sotto, Rob Pitt and Guillaume
|
7
|
+
Pierronnet for making this release possible.
|
8
|
+
|
9
|
+
Most notable changes:
|
10
|
+
|
11
|
+
* Og now supports calculations and aggregations. Here are some
|
12
|
+
examples:
|
13
|
+
|
14
|
+
User.min(:age)
|
15
|
+
User.average(:age)
|
16
|
+
User.maximum(:age)
|
17
|
+
User.min(:age, :group => :profession) # => [..] (aggregation)
|
18
|
+
User.sum(:age, :group => :role) # => [..]
|
19
|
+
|
20
|
+
and more!
|
21
|
+
|
22
|
+
* Improved Taggable mixin, now provides more helpers and supports
|
23
|
+
tag garbage collection through reference counting.
|
24
|
+
|
25
|
+
* Added a new store for the generalized caching system that is
|
26
|
+
backed by a MemCache server. Useful to extract the last ounch
|
27
|
+
of performance in a production environment.
|
28
|
+
|
29
|
+
* Many Og bug fixes and optimizations.
|
30
|
+
|
31
|
+
* Many, many bug fixes and small improvements throughout the
|
32
|
+
code.
|
33
|
+
|
34
|
+
|
1
35
|
== Version 0.28.0
|
2
36
|
|
3
37
|
A snapshot of the latest developments. As always, cool new
|
data/lib/glue/cacheable.rb
CHANGED
@@ -125,6 +125,7 @@ module Cacheable
|
|
125
125
|
# ...
|
126
126
|
|
127
127
|
def self.cache_get(klass, pk)
|
128
|
+
obj.class.ogmanager.cache.get(klass.og_cache_key(pk))
|
128
129
|
end
|
129
130
|
|
130
131
|
# ...
|
@@ -140,7 +141,8 @@ module Cacheable
|
|
140
141
|
# SQL query) you should call this method explicitly.
|
141
142
|
|
142
143
|
def self.cache_delete(klass, pk)
|
143
|
-
key = "og#{klass}:#{pk}"
|
144
|
+
#key = "og#{klass}:#{pk}"
|
145
|
+
key = klass.og_cache_key(pk)
|
144
146
|
# self.og_local_cache.delete(key)
|
145
147
|
klass.ogmanager.cache.delete(key)
|
146
148
|
end
|
data/lib/glue/hierarchical.rb
CHANGED
@@ -12,7 +12,7 @@ module Glue
|
|
12
12
|
|
13
13
|
module NestedSets
|
14
14
|
|
15
|
-
def self.
|
15
|
+
def self.included_with_parameters(base, options)
|
16
16
|
c = {
|
17
17
|
:left => 'lft',
|
18
18
|
:right => 'rgt',
|
@@ -100,8 +100,8 @@ module NestedSets
|
|
100
100
|
@#{right} = pivot + 2
|
101
101
|
|
102
102
|
#{base}.transaction do
|
103
|
-
#{base}.
|
104
|
-
#{base}.
|
103
|
+
#{base}.update("#{left} = (#{left} + 2)", #{cond_and}"#{left} >= \#{pivot}")
|
104
|
+
#{base}.update("#{right} = (#{right} + 2)", #{cond_and}"#{right} >= \#{pivot}")
|
105
105
|
end
|
106
106
|
|
107
107
|
self.save
|
data/lib/glue/orderable.rb
CHANGED
data/lib/glue/taggable.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'facet/inflect'
|
2
2
|
|
3
|
+
module Glue
|
4
|
+
|
3
5
|
# The default Tag implementation. A tag attaches semantics to
|
4
6
|
# a given object.
|
5
7
|
#--
|
@@ -20,18 +22,49 @@ class Tag
|
|
20
22
|
@count = 0
|
21
23
|
end
|
22
24
|
|
23
|
-
|
24
|
-
# FIXME: use update_properties here!
|
25
|
-
#++
|
25
|
+
# Tag an object.
|
26
26
|
|
27
27
|
def tag(obj)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
#--
|
29
|
+
# FIXME: this does not work as expected :( it alters
|
30
|
+
# the @loaded flag in the obj.tags collection without
|
31
|
+
# setting the @members.
|
32
|
+
# INVESTIGATE: why this happens!
|
33
|
+
#
|
34
|
+
# return if obj.tagged_with?(@name)
|
35
|
+
# class_name = obj.class.name
|
36
|
+
# method_name = class_name.index('::') ? (class_name =~ /.*?\:\:(.*)/; $1) : class_name
|
37
|
+
# send(method_name.pluralize.underscore.to_sym) << obj
|
38
|
+
#++
|
39
|
+
|
40
|
+
unless obj.tagged_with?(name)
|
41
|
+
obj.tags << self
|
42
|
+
@count += 1
|
43
|
+
update_property :count
|
44
|
+
end
|
34
45
|
end
|
46
|
+
alias_method :link, :tag
|
47
|
+
|
48
|
+
# Untags an object. If no object is passed, it just decrements
|
49
|
+
# the (reference) count. If the count reaches 0 the tag is
|
50
|
+
# deleted (garbage collection).
|
51
|
+
|
52
|
+
def untag(obj = nil)
|
53
|
+
if obj
|
54
|
+
# TODO: implement me.
|
55
|
+
end
|
56
|
+
|
57
|
+
@count -= 1
|
58
|
+
|
59
|
+
if @count > 0
|
60
|
+
p "-- dec ref count"
|
61
|
+
update_property :count
|
62
|
+
else
|
63
|
+
p "-- count = 0 -> delete"
|
64
|
+
self.delete()
|
65
|
+
end
|
66
|
+
end
|
67
|
+
alias_method :unlink, :untag
|
35
68
|
|
36
69
|
# Return all tagged objects from all categories.
|
37
70
|
|
@@ -50,8 +83,6 @@ class Tag
|
|
50
83
|
end
|
51
84
|
end
|
52
85
|
|
53
|
-
module Glue
|
54
|
-
|
55
86
|
# Add tagging methods to the target class.
|
56
87
|
# For more information on the algorithms used surf:
|
57
88
|
# http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
|
@@ -87,13 +118,32 @@ module Taggable
|
|
87
118
|
:clear => true
|
88
119
|
}.merge(options)
|
89
120
|
|
90
|
-
|
121
|
+
delete_all_tags() if options[:clear]
|
91
122
|
|
92
123
|
for name in Taggable.tags_to_names(the_tags)
|
93
|
-
Tag.find_or_create_by_name(name)
|
124
|
+
the_tag = Tag.find_or_create_by_name(name)
|
125
|
+
the_tag.tag(self)
|
94
126
|
end
|
95
127
|
end
|
96
128
|
alias_method :tag!, :tag
|
129
|
+
|
130
|
+
# Delete a single tag from this taggable object.
|
131
|
+
|
132
|
+
def delete_tag(name)
|
133
|
+
if dtag = (tags.delete_if { |t| t.name == name }).first
|
134
|
+
dtag.unlink
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Delete all tags from this taggable object.
|
139
|
+
|
140
|
+
def delete_all_tags
|
141
|
+
for tag in tags
|
142
|
+
tag.unlink
|
143
|
+
end
|
144
|
+
tags.clear
|
145
|
+
end
|
146
|
+
alias_method :clear_tags, :delete_all_tags
|
97
147
|
|
98
148
|
# Return the names of the tags.
|
99
149
|
|
@@ -124,16 +174,16 @@ module Taggable
|
|
124
174
|
count = names.size
|
125
175
|
names = names.map { |n| ogmanager.store.quote(n) }.join(',')
|
126
176
|
sql = %{
|
127
|
-
SELECT
|
177
|
+
SELECT t.*
|
128
178
|
FROM
|
129
179
|
#{info[:first_table]} AS o,
|
130
180
|
#{info[:second_table]} as t,
|
131
181
|
#{info[:table]} as j
|
132
182
|
WHERE o.oid = j.#{info[:first_key]}
|
133
183
|
AND t.oid = j.#{info[:second_key]}
|
134
|
-
AND (
|
135
|
-
GROUP BY
|
136
|
-
HAVING COUNT(
|
184
|
+
AND (o.name in (#{names}))
|
185
|
+
GROUP BY j.article_oid
|
186
|
+
HAVING COUNT(j.article_oid) = #{count};
|
137
187
|
}
|
138
188
|
return self.select(sql)
|
139
189
|
end
|
@@ -147,7 +197,7 @@ module Taggable
|
|
147
197
|
count = names.size
|
148
198
|
names = names.map { |n| ogmanager.store.quote(n) }.join(',')
|
149
199
|
sql = %{
|
150
|
-
SELECT
|
200
|
+
SELECT t.*
|
151
201
|
FROM
|
152
202
|
#{info[:first_table]} AS o,
|
153
203
|
#{info[:second_table]} as t,
|
@@ -155,8 +205,8 @@ module Taggable
|
|
155
205
|
WHERE
|
156
206
|
o.oid = j.#{info[:first_key]}
|
157
207
|
AND t.oid = j.#{info[:second_key]}
|
158
|
-
AND (
|
159
|
-
GROUP BY
|
208
|
+
AND (o.name in (#{names}))
|
209
|
+
GROUP BY j.article_oid
|
160
210
|
}
|
161
211
|
return self.select(sql)
|
162
212
|
end
|
@@ -170,7 +220,7 @@ module Taggable
|
|
170
220
|
#--
|
171
221
|
# FIXME: Og should handle this automatically.
|
172
222
|
#++
|
173
|
-
base.send :include, Aspects
|
223
|
+
base.send :include, Glue::Aspects
|
174
224
|
base.before 'tags.clear', :on => [:og_delete]
|
175
225
|
end
|
176
226
|
|
data/lib/glue/timestamped.rb
CHANGED
@@ -7,7 +7,7 @@ module Glue
|
|
7
7
|
# Adds timestamping functionality.
|
8
8
|
|
9
9
|
module Timestamped
|
10
|
-
include Aspects
|
10
|
+
include Glue::Aspects
|
11
11
|
|
12
12
|
property :create_time, Time, :control => :none
|
13
13
|
property :update_time, Time, :control => :none
|
@@ -27,7 +27,7 @@ end
|
|
27
27
|
# module.
|
28
28
|
|
29
29
|
module TimestampedOnCreate
|
30
|
-
include Aspects
|
30
|
+
include Glue::Aspects
|
31
31
|
property :create_time, Time, :control => :none
|
32
32
|
before "@create_time = Time.now", :on => :og_insert
|
33
33
|
end
|
data/lib/og.rb
CHANGED
@@ -43,7 +43,7 @@ module Og
|
|
43
43
|
|
44
44
|
# The version.
|
45
45
|
|
46
|
-
Version = '0.
|
46
|
+
Version = '0.29.0'
|
47
47
|
|
48
48
|
# Library path.
|
49
49
|
|
@@ -93,7 +93,7 @@ module Og
|
|
93
93
|
|
94
94
|
# Enable/dissable thread safe mode.
|
95
95
|
|
96
|
-
setting :thread_safe, :default => true, :doc => 'Enable/dissable thread safe mode'
|
96
|
+
#setting :thread_safe, :default => true, :doc => 'Enable/dissable thread safe mode'
|
97
97
|
|
98
98
|
# Address of the Og cache (if distributed caching enabled).
|
99
99
|
|
@@ -107,6 +107,10 @@ module Og
|
|
107
107
|
|
108
108
|
mattr_accessor :manager
|
109
109
|
|
110
|
+
# thread safe state
|
111
|
+
|
112
|
+
mattr_reader :thread_safe
|
113
|
+
|
110
114
|
# Pseudo type for binary data
|
111
115
|
|
112
116
|
class Blob; end
|
@@ -124,7 +128,9 @@ module Og
|
|
124
128
|
# additional, faster or enhanced functionality.
|
125
129
|
|
126
130
|
options[:called_by_og_setup] = true if options[:called_by_og_setup].nil?
|
127
|
-
|
131
|
+
|
132
|
+
@@thread_safe = true
|
133
|
+
|
128
134
|
m = @@manager = Manager.new(options)
|
129
135
|
m.manage_classes
|
130
136
|
|
@@ -155,6 +161,13 @@ module Og
|
|
155
161
|
def escape(str)
|
156
162
|
@@manager.store.escape(str)
|
157
163
|
end
|
164
|
+
|
165
|
+
# change thread_safe mode
|
166
|
+
def thread_safe=(bool)
|
167
|
+
@@thread_safe = bool
|
168
|
+
@@manager and @@manager.class.managers.each { |m| m.initialize_store }
|
169
|
+
@@thread_safe
|
170
|
+
end
|
158
171
|
end
|
159
172
|
|
160
173
|
end
|
data/lib/og/entity.rb
CHANGED
@@ -221,13 +221,56 @@ module EntityMixin
|
|
221
221
|
ogmanager.store.select_one(sql, self)
|
222
222
|
end
|
223
223
|
|
224
|
+
# :section: Aggregations / Calculations
|
225
|
+
|
226
|
+
# Perform a general aggregation/calculation.
|
227
|
+
|
228
|
+
def aggregate(term, options = {})
|
229
|
+
options[:class] = self
|
230
|
+
ogmanager.store.calculate(term, options)
|
231
|
+
end
|
232
|
+
alias_method :calculate, :aggregate
|
233
|
+
|
224
234
|
# Perform a count query.
|
225
235
|
|
226
236
|
def count(options = {})
|
227
|
-
options
|
228
|
-
|
237
|
+
calculate('COUNT(*)', options).to_i
|
238
|
+
end
|
239
|
+
|
240
|
+
# Find the minimum of a property.
|
241
|
+
# Pass a :group option to return an aggregation.
|
242
|
+
|
243
|
+
def minimum(min, options = {})
|
244
|
+
calculate("MIN(#{min})", options)
|
245
|
+
end
|
246
|
+
alias_method :min, :minimum
|
247
|
+
|
248
|
+
# Find the maximum of a property.
|
249
|
+
# Pass a :group option to return an aggregation.
|
250
|
+
|
251
|
+
def maximum(max, options = {})
|
252
|
+
calculate("MAX(#{max})", options)
|
229
253
|
end
|
254
|
+
alias_method :max, :maximum
|
230
255
|
|
256
|
+
# Find the average of a property.
|
257
|
+
# Pass a :group option to return an aggregation.
|
258
|
+
|
259
|
+
def average(avg, options = {})
|
260
|
+
calculate("AVG(#{avg})", options)
|
261
|
+
end
|
262
|
+
alias_method :avg, :average
|
263
|
+
|
264
|
+
# Find the sum of a property.
|
265
|
+
# Pass a :group option to return an aggregation.
|
266
|
+
|
267
|
+
def summarize(sum, options = {})
|
268
|
+
calculate("SUM(#{sum})", options)
|
269
|
+
end
|
270
|
+
alias_method :sum, :summarize
|
271
|
+
|
272
|
+
# :section: Delete/Destroy methods.
|
273
|
+
|
231
274
|
# Delete an instance of this Entity class using the actual
|
232
275
|
# instance or the primary key.
|
233
276
|
|
@@ -497,19 +540,24 @@ private
|
|
497
540
|
def finder(match, args)
|
498
541
|
finder = (match.captures.first == 'all_by' ? :find : :find_one)
|
499
542
|
attrs = match.captures.last.split('_and_')
|
500
|
-
|
501
|
-
options = {}
|
543
|
+
options = (annotation[:find_options] || {}).dup
|
502
544
|
options = args.pop if args.last.is_a?(Hash)
|
503
|
-
|
545
|
+
relations_map = relations.map{|r| [r.name.to_s,r]}
|
504
546
|
condition = attrs.zip(args).map do |name, value|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
547
|
+
if relation = relations_map.assoc(name)
|
548
|
+
relation = relation.last
|
549
|
+
field_name = relation.foreign_key
|
550
|
+
value = value.send(relation.target_class.primary_key.symbol)
|
551
|
+
else
|
552
|
+
field_name = properties[name.to_sym][:field] ||
|
553
|
+
properties[name.to_sym][:name] ||
|
554
|
+
properties[name.to_sym][:symbol]
|
555
|
+
end
|
556
|
+
options["#{name}_op".to_sym] = 'IN' if value.is_a?(Array)
|
509
557
|
%|#{field_name} #{options.delete("#{name}_op".to_sym) || '='} #{ogmanager.store.quote(value)}|
|
510
558
|
end.join(' AND ')
|
511
559
|
|
512
|
-
options.
|
560
|
+
options.merge!(
|
513
561
|
:class => self,
|
514
562
|
:condition => condition
|
515
563
|
)
|
data/lib/og/ez/clause.rb
CHANGED
@@ -95,7 +95,8 @@ module Caboose
|
|
95
95
|
when :between
|
96
96
|
@negate ? ["#{@table_prefix}#{@name} NOT BETWEEN ? AND ?", @value.begin, @value.end] : ["#{@table_prefix}#{@name} BETWEEN ? AND ?", @value.begin, @value.end]
|
97
97
|
when :in
|
98
|
-
@negate ? ["#{@table_prefix}#{@name} NOT IN (?)", @value.to_a] : ["#{@table_prefix}#{@name} IN (?)", @value.to_a]
|
98
|
+
# @negate ? ["#{@table_prefix}#{@name} NOT IN (?)", @value.to_a] : ["#{@table_prefix}#{@name} IN (?)", @value.to_a]
|
99
|
+
@negate ? ["#{@table_prefix}#{@name} NOT IN (?*)", @value.to_a] : ["#{@table_prefix}#{@name} IN (?*)", @value.to_a]
|
99
100
|
else
|
100
101
|
["#{@table_prefix}#{@name} #{@test} ?", @value]
|
101
102
|
end
|
data/lib/og/manager.rb
CHANGED
@@ -13,13 +13,18 @@ class Manager
|
|
13
13
|
def self.managers
|
14
14
|
managers = []
|
15
15
|
ObjectSpace.each_object(self) { |o| managers << o }
|
16
|
-
managers
|
16
|
+
return managers
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.managed?(klass)
|
20
20
|
self.managers.any? { |m| m.managed? klass }
|
21
21
|
end
|
22
22
|
|
23
|
+
def self.managed_classes
|
24
|
+
managed = self.managers.collect {|m| m.managed_classes}
|
25
|
+
managed.flatten
|
26
|
+
end
|
27
|
+
|
23
28
|
# Information about an Entity class.
|
24
29
|
|
25
30
|
class EntityInfo
|
@@ -56,28 +61,51 @@ class Manager
|
|
56
61
|
def initialize(options)
|
57
62
|
@options = options
|
58
63
|
@entities = {}
|
59
|
-
@pool = Pool.new
|
60
64
|
|
61
65
|
@store_class = Store.for_name(options[:store])
|
62
66
|
@store_class.destroy(options) if options[:destroy]
|
63
67
|
@store_class.destroy_tables(options) if options[:destroy_tables]
|
68
|
+
init_store
|
69
|
+
end
|
70
|
+
|
71
|
+
def initialize_store
|
72
|
+
if @pool
|
73
|
+
close_store
|
74
|
+
end
|
64
75
|
|
65
76
|
if Og.thread_safe
|
77
|
+
@pool = Pool.new
|
66
78
|
(options[:connection_count] || 5).times do
|
67
|
-
@pool << @store_class.new(options)
|
79
|
+
@pool << @store_class.new(@options)
|
68
80
|
end
|
69
81
|
else
|
70
|
-
@store = @store_class.new(options)
|
82
|
+
@store = @store_class.new(@options)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
alias :init_store :initialize_store
|
86
|
+
|
87
|
+
# used when changing thread_safe mode
|
88
|
+
|
89
|
+
def close_store
|
90
|
+
if @pool.empty?
|
91
|
+
@store.close
|
92
|
+
else
|
93
|
+
@pool.each { |s| s.close }
|
94
|
+
@pool.clear
|
71
95
|
end
|
96
|
+
@pool = nil
|
72
97
|
end
|
73
98
|
|
74
99
|
# Get a store from the pool.
|
75
100
|
|
76
101
|
def get_store
|
77
|
-
if
|
102
|
+
if @pool
|
78
103
|
thread = Thread.current
|
79
104
|
|
80
105
|
unless st = thread[:og_store] and st.is_a?(@store_class)
|
106
|
+
if 0 == @pool.size()
|
107
|
+
initialize_store()
|
108
|
+
end
|
81
109
|
st = @pool.pop()
|
82
110
|
thread[:og_store] = st
|
83
111
|
end
|
@@ -93,7 +121,7 @@ class Manager
|
|
93
121
|
# Return a store to the pool.
|
94
122
|
|
95
123
|
def put_store
|
96
|
-
if
|
124
|
+
if @pool
|
97
125
|
thread = Thread.current
|
98
126
|
|
99
127
|
if conn = thread[:og_store]
|
@@ -150,7 +178,7 @@ class Manager
|
|
150
178
|
#++
|
151
179
|
|
152
180
|
def manageable?(klass)
|
153
|
-
klass.respond_to?(:properties) and (!klass.properties.empty?) # and
|
181
|
+
klass.respond_to?(:properties) and (!klass.properties.empty?) # and klass.ann.self.polymorphic.nil?
|
154
182
|
end
|
155
183
|
|
156
184
|
# Is the class managed by Og?
|
@@ -186,6 +214,7 @@ class Manager
|
|
186
214
|
|
187
215
|
def manage_classes(*classes)
|
188
216
|
classes = manageable_classes.flatten # if classes.empty? FIXME!
|
217
|
+
classes = classes.reject { |c| self.class.managed?(c) }
|
189
218
|
|
190
219
|
classes.each { |c| Relation.resolve_targets(c) }
|
191
220
|
classes.each { |c| Relation.resolve_polymorphic_markers(c) }
|
@@ -194,6 +223,7 @@ class Manager
|
|
194
223
|
# The polymorpic resolution step creates more manageable classes.
|
195
224
|
|
196
225
|
classes = manageable_classes.flatten # if classes.empty? FIXME!
|
226
|
+
classes = classes.reject { |c| self.class.managed?(c) }
|
197
227
|
|
198
228
|
Logger.debug "Og manageable classes: #{classes.inspect}" if $DBG
|
199
229
|
|
@@ -241,3 +271,4 @@ end
|
|
241
271
|
|
242
272
|
# * George Moschovitis <gm@navel.gr>
|
243
273
|
# * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
|
274
|
+
# * Rob Pitt
|