amoeba 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.cane +4 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +13 -5
- data/Appraisals +24 -0
- data/Gemfile +6 -4
- data/README.md +134 -44
- data/Rakefile +2 -2
- data/amoeba.gemspec +20 -15
- data/defaults.reek +11 -0
- data/gemfiles/activerecord_3.2.gemfile +17 -0
- data/gemfiles/activerecord_4.0.gemfile +17 -0
- data/gemfiles/activerecord_4.1.gemfile +17 -0
- data/gemfiles/activerecord_4.2.gemfile +17 -0
- data/gemfiles/activerecord_head.gemfile +23 -0
- data/lib/amoeba.rb +13 -522
- data/lib/amoeba/class_methods.rb +23 -0
- data/lib/amoeba/cloner.rb +168 -0
- data/lib/amoeba/config.rb +172 -0
- data/lib/amoeba/instance_methods.rb +37 -0
- data/lib/amoeba/macros.rb +14 -0
- data/lib/amoeba/macros/base.rb +26 -0
- data/lib/amoeba/macros/has_and_belongs_to_many.rb +19 -0
- data/lib/amoeba/macros/has_many.rb +42 -0
- data/lib/amoeba/macros/has_one.rb +15 -0
- data/lib/amoeba/version.rb +1 -1
- data/spec/lib/amoeba_spec.rb +180 -87
- data/spec/spec_helper.rb +23 -4
- data/spec/support/data.rb +73 -73
- data/spec/support/models.rb +132 -28
- data/spec/support/schema.rb +69 -42
- metadata +38 -29
- data/.ruby-version +0 -1
- data/gemfiles/Gemfile.activerecord-3.2.x +0 -11
- data/gemfiles/Gemfile.activerecord-4.0.x +0 -11
data/spec/support/models.rb
CHANGED
@@ -7,7 +7,7 @@ class User < ActiveRecord::Base
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class Author < ActiveRecord::Base
|
10
|
-
has_many :posts, :
|
10
|
+
has_many :posts, inverse_of: :author
|
11
11
|
amoeba do
|
12
12
|
enable
|
13
13
|
end
|
@@ -15,16 +15,16 @@ end
|
|
15
15
|
|
16
16
|
class Post < ActiveRecord::Base
|
17
17
|
belongs_to :topic
|
18
|
-
belongs_to :owner, :
|
19
|
-
belongs_to :author, :
|
18
|
+
belongs_to :owner, class_name: 'User'
|
19
|
+
belongs_to :author, inverse_of: :posts
|
20
20
|
has_one :post_config
|
21
21
|
has_one :account
|
22
|
-
has_one :history, :
|
22
|
+
has_one :history, through: :account
|
23
23
|
has_many :comments
|
24
24
|
has_many :supercats
|
25
|
-
has_many :categories, :
|
25
|
+
has_many :categories, through: :supercats
|
26
26
|
has_many :post_widgets
|
27
|
-
has_many :widgets, :
|
27
|
+
has_many :widgets, through: :post_widgets
|
28
28
|
has_many :custom_things
|
29
29
|
has_and_belongs_to_many :tags
|
30
30
|
has_and_belongs_to_many :notes
|
@@ -35,13 +35,13 @@ class Post < ActiveRecord::Base
|
|
35
35
|
amoeba do
|
36
36
|
enable
|
37
37
|
clone [:widgets, :notes]
|
38
|
-
prepend :
|
39
|
-
append :
|
40
|
-
regex :
|
38
|
+
prepend title: 'Copy of '
|
39
|
+
append contents: ' (copied version)'
|
40
|
+
regex contents: { replace: /dog/, with: 'cat' }
|
41
41
|
customize([
|
42
|
-
lambda do |orig_obj,copy_of_obj|
|
42
|
+
lambda do |orig_obj, copy_of_obj|
|
43
43
|
orig_obj.comments.each do |oc|
|
44
|
-
if oc.nerf ==
|
44
|
+
if oc.nerf == 'ratatat'
|
45
45
|
hash = oc.attributes
|
46
46
|
hash[:id] = nil
|
47
47
|
hash[:post_id] = nil
|
@@ -53,14 +53,14 @@ class Post < ActiveRecord::Base
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end,
|
56
|
-
lambda do |orig_obj,copy_of_obj|
|
56
|
+
lambda do |orig_obj, copy_of_obj|
|
57
57
|
orig_obj.comments.each do |oc|
|
58
|
-
if oc.nerf ==
|
58
|
+
if oc.nerf == 'bonk'
|
59
59
|
hash = oc.attributes
|
60
60
|
hash[:id] = nil
|
61
61
|
hash[:post_id] = nil
|
62
62
|
hash[:contents] = nil
|
63
|
-
hash[:nerf] =
|
63
|
+
hash[:nerf] = 'bonkers'
|
64
64
|
|
65
65
|
cc = Comment.new(hash)
|
66
66
|
|
@@ -82,11 +82,11 @@ class CustomThing < ActiveRecord::Base
|
|
82
82
|
if str.is_a?(Array)
|
83
83
|
return str
|
84
84
|
end
|
85
|
-
str.split(',').
|
85
|
+
str.split(',').map(&:to_i)
|
86
86
|
end
|
87
87
|
def self.dump(int_array)
|
88
88
|
unless int_array.present? && int_array.length > 0
|
89
|
-
return
|
89
|
+
return ''
|
90
90
|
end
|
91
91
|
int_array.join(',')
|
92
92
|
end
|
@@ -96,7 +96,7 @@ class CustomThing < ActiveRecord::Base
|
|
96
96
|
|
97
97
|
before_create :hydrate_me
|
98
98
|
def hydrate_me
|
99
|
-
self.value =
|
99
|
+
self.value = value
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
@@ -115,12 +115,12 @@ end
|
|
115
115
|
|
116
116
|
class Category < ActiveRecord::Base
|
117
117
|
has_many :supercats
|
118
|
-
has_many :posts, :
|
118
|
+
has_many :posts, through: :supercats
|
119
119
|
|
120
120
|
amoeba do
|
121
121
|
enable
|
122
|
-
prepend :
|
123
|
-
set :
|
122
|
+
prepend ramblings: 'Copy of '
|
123
|
+
set other_ramblings: 'La la la'
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -130,9 +130,9 @@ class Supercat < ActiveRecord::Base
|
|
130
130
|
has_many :superkittens
|
131
131
|
|
132
132
|
amoeba do
|
133
|
-
|
134
|
-
prepend :
|
135
|
-
set :
|
133
|
+
include_association :superkittens
|
134
|
+
prepend ramblings: 'Copy of '
|
135
|
+
set other_ramblings: 'La la la'
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
@@ -150,7 +150,7 @@ class Comment < ActiveRecord::Base
|
|
150
150
|
has_many :reviews
|
151
151
|
|
152
152
|
amoeba do
|
153
|
-
|
153
|
+
exclude_association :reviews
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -164,7 +164,7 @@ end
|
|
164
164
|
|
165
165
|
class Widget < ActiveRecord::Base
|
166
166
|
has_many :post_widgets
|
167
|
-
has_many :posts, :
|
167
|
+
has_many :posts, through: :post_widgets
|
168
168
|
end
|
169
169
|
|
170
170
|
class PostWidget < ActiveRecord::Base
|
@@ -204,21 +204,125 @@ class Shirt < Product
|
|
204
204
|
end
|
205
205
|
|
206
206
|
class Necklace < Product
|
207
|
+
# Strange bug on rbx
|
208
|
+
if defined?(::Rubinius)
|
209
|
+
after_initialize :set_type
|
210
|
+
|
211
|
+
def set_type
|
212
|
+
self.type = 'Necklace'
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
207
216
|
amoeba do
|
208
217
|
raised :relaxed
|
209
218
|
end
|
210
219
|
end
|
211
220
|
|
221
|
+
class BlackBox < Product
|
222
|
+
amoeba do
|
223
|
+
propagate :strict
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
class SuperBlackBox < BlackBox
|
228
|
+
end
|
229
|
+
|
212
230
|
# Polymorphism
|
213
231
|
class Address < ActiveRecord::Base
|
214
|
-
belongs_to :addressable, :
|
232
|
+
belongs_to :addressable, polymorphic: true
|
215
233
|
end
|
216
234
|
|
217
235
|
class Employee < ActiveRecord::Base
|
218
|
-
has_many :addresses, :
|
236
|
+
has_many :addresses, as: :addressable
|
219
237
|
end
|
220
238
|
|
221
239
|
class Customer < ActiveRecord::Base
|
222
|
-
has_many :addresses, :
|
240
|
+
has_many :addresses, as: :addressable
|
241
|
+
end
|
242
|
+
|
243
|
+
# Remapping and Method
|
244
|
+
|
245
|
+
class MetalObject < ActiveRecord::Base
|
246
|
+
end
|
247
|
+
|
248
|
+
class ObjectPrototype < MetalObject
|
249
|
+
has_many :subobject_prototypes, foreign_key: :parent_id
|
250
|
+
|
251
|
+
amoeba do
|
252
|
+
enable
|
253
|
+
through :become_real
|
254
|
+
remapper :remap_subobjects
|
255
|
+
end
|
256
|
+
|
257
|
+
def become_real
|
258
|
+
self.dup.becomes RealObject
|
259
|
+
end
|
260
|
+
|
261
|
+
def remap_subobjects( relation_name )
|
262
|
+
:subobjects if relation_name == :subobject_prototypes
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class RealObject < MetalObject
|
267
|
+
has_many :subobjects, foreign_key: :parent_id
|
268
|
+
end
|
269
|
+
|
270
|
+
class SubobjectPrototype < MetalObject
|
271
|
+
|
272
|
+
amoeba do
|
273
|
+
enable
|
274
|
+
through :become_subobject
|
275
|
+
end
|
276
|
+
|
277
|
+
def become_subobject
|
278
|
+
self.dup.becomes Subobject
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
class Subobject < MetalObject
|
283
|
+
end
|
284
|
+
|
285
|
+
# Check of changing boolean attributes
|
286
|
+
|
287
|
+
class SuperAdmin < ::ActiveRecord::Base
|
288
|
+
|
289
|
+
amoeba do
|
290
|
+
set active: false
|
291
|
+
prepend password: false
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
# Proper inheritance
|
296
|
+
|
297
|
+
class Box < ActiveRecord::Base
|
298
|
+
|
299
|
+
has_many :products, class_name: 'BoxProduct'
|
300
|
+
has_many :sub_products, class_name: 'BoxSubProduct'
|
301
|
+
|
302
|
+
amoeba do
|
303
|
+
enable
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
class BoxProduct < ActiveRecord::Base
|
309
|
+
|
310
|
+
belongs_to :box, class_name: 'Box'
|
311
|
+
|
312
|
+
amoeba do
|
313
|
+
enable
|
314
|
+
propagate
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
class BoxSubProduct < BoxProduct
|
320
|
+
has_one :another_product, class_name: 'BoxAnotherProduct'
|
321
|
+
end
|
322
|
+
|
323
|
+
class BoxSubSubProduct < BoxSubProduct
|
223
324
|
end
|
224
325
|
|
326
|
+
class BoxAnotherProduct < BoxProduct
|
327
|
+
belongs_to :sub_product, class_name: 'BoxSubProduct'
|
328
|
+
end
|
data/spec/support/schema.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
2
|
self.verbose = false
|
3
3
|
|
4
|
-
create_table :topics, :
|
4
|
+
create_table :topics, force: true do |t|
|
5
5
|
t.string :title
|
6
6
|
t.string :description
|
7
|
-
t.timestamps
|
7
|
+
t.timestamps null: true
|
8
8
|
end
|
9
9
|
|
10
|
-
create_table :posts, :
|
10
|
+
create_table :posts, force: true do |t|
|
11
11
|
t.integer :topic_id
|
12
12
|
t.integer :owner_id
|
13
13
|
t.integer :author_id
|
14
14
|
t.string :title
|
15
15
|
t.string :contents
|
16
|
-
t.timestamps
|
16
|
+
t.timestamps null: true
|
17
17
|
end
|
18
18
|
|
19
|
-
create_table :products, :
|
19
|
+
create_table :products, force: true do |t|
|
20
20
|
t.string :type
|
21
21
|
t.string :title
|
22
22
|
t.decimal :price
|
@@ -28,35 +28,35 @@ ActiveRecord::Schema.define do
|
|
28
28
|
t.string :metal
|
29
29
|
end
|
30
30
|
|
31
|
-
create_table :products_sections, :
|
31
|
+
create_table :products_sections, force: true do |t|
|
32
32
|
t.integer :section_id
|
33
33
|
t.integer :product_id
|
34
34
|
end
|
35
35
|
|
36
|
-
create_table :sections, :
|
36
|
+
create_table :sections, force: true do |t|
|
37
37
|
t.string :name
|
38
38
|
t.integer :num_employees
|
39
39
|
t.decimal :total_sales
|
40
40
|
end
|
41
41
|
|
42
|
-
create_table :images, :
|
42
|
+
create_table :images, force: true do |t|
|
43
43
|
t.string :filename
|
44
44
|
t.integer :product_id
|
45
45
|
end
|
46
46
|
|
47
|
-
create_table :employees, :
|
47
|
+
create_table :employees, force: true do |t|
|
48
48
|
t.string :name
|
49
49
|
t.string :ssn
|
50
50
|
t.decimal :salary
|
51
51
|
end
|
52
52
|
|
53
|
-
create_table :customers, :
|
53
|
+
create_table :customers, force: true do |t|
|
54
54
|
t.string :email
|
55
55
|
t.string :password
|
56
56
|
t.decimal :balance
|
57
57
|
end
|
58
58
|
|
59
|
-
create_table :addresses, :
|
59
|
+
create_table :addresses, force: true do |t|
|
60
60
|
t.integer :addressable_id
|
61
61
|
t.string :addressable_type
|
62
62
|
|
@@ -67,109 +67,136 @@ ActiveRecord::Schema.define do
|
|
67
67
|
t.string :zip
|
68
68
|
end
|
69
69
|
|
70
|
-
create_table :post_configs, :
|
70
|
+
create_table :post_configs, force: true do |t|
|
71
71
|
t.integer :post_id
|
72
72
|
t.integer :is_visible
|
73
73
|
t.integer :is_open
|
74
74
|
t.string :password
|
75
|
-
t.timestamps
|
75
|
+
t.timestamps null: true
|
76
76
|
end
|
77
77
|
|
78
|
-
create_table :comments, :
|
78
|
+
create_table :comments, force: true do |t|
|
79
79
|
t.integer :post_id
|
80
80
|
t.string :contents
|
81
|
-
t.timestamps
|
81
|
+
t.timestamps null: true
|
82
82
|
end
|
83
83
|
|
84
|
-
create_table :custom_things, :
|
84
|
+
create_table :custom_things, force: true do |t|
|
85
85
|
t.integer :post_id
|
86
86
|
t.string :value
|
87
|
-
t.timestamps
|
87
|
+
t.timestamps null: true
|
88
88
|
end
|
89
89
|
|
90
|
-
create_table :comments, :
|
90
|
+
create_table :comments, force: true do |t|
|
91
91
|
t.integer :post_id
|
92
92
|
t.string :contents
|
93
93
|
t.string :nerf
|
94
|
-
t.timestamps
|
94
|
+
t.timestamps null: true
|
95
95
|
end
|
96
96
|
|
97
|
-
create_table :ratings, :
|
97
|
+
create_table :ratings, force: true do |t|
|
98
98
|
t.integer :comment_id
|
99
99
|
t.string :num_stars
|
100
|
-
t.timestamps
|
100
|
+
t.timestamps null: true
|
101
101
|
end
|
102
102
|
|
103
|
-
create_table :tags, :
|
103
|
+
create_table :tags, force: true do |t|
|
104
104
|
t.string :value
|
105
|
-
t.timestamps
|
105
|
+
t.timestamps null: true
|
106
106
|
end
|
107
107
|
|
108
|
-
create_table :users, :
|
108
|
+
create_table :users, force: true do |t|
|
109
109
|
t.integer :post_id
|
110
110
|
t.string :name
|
111
111
|
t.string :email
|
112
|
-
t.timestamps
|
112
|
+
t.timestamps null: true
|
113
113
|
end
|
114
114
|
|
115
|
-
create_table :authors, :
|
115
|
+
create_table :authors, force: true do |t|
|
116
116
|
t.string :full_name
|
117
117
|
t.string :nickname
|
118
|
-
t.timestamps
|
118
|
+
t.timestamps null: true
|
119
119
|
end
|
120
120
|
|
121
|
-
create_table :posts_tags, :
|
121
|
+
create_table :posts_tags, force: true do |t|
|
122
122
|
t.integer :post_id
|
123
123
|
t.integer :tag_id
|
124
124
|
end
|
125
125
|
|
126
|
-
create_table :notes, :
|
126
|
+
create_table :notes, force: true do |t|
|
127
127
|
t.string :value
|
128
|
-
t.timestamps
|
128
|
+
t.timestamps null: true
|
129
129
|
end
|
130
130
|
|
131
|
-
create_table :notes_posts, :
|
131
|
+
create_table :notes_posts, force: true do |t|
|
132
132
|
t.integer :post_id
|
133
133
|
t.integer :note_id
|
134
134
|
end
|
135
135
|
|
136
|
-
create_table :widgets, :
|
136
|
+
create_table :widgets, force: true do |t|
|
137
137
|
t.string :value
|
138
138
|
end
|
139
139
|
|
140
|
-
create_table :post_widgets, :
|
140
|
+
create_table :post_widgets, force: true do |t|
|
141
141
|
t.integer :post_id
|
142
142
|
t.integer :widget_id
|
143
143
|
end
|
144
144
|
|
145
|
-
create_table :categories, :
|
145
|
+
create_table :categories, force: true do |t|
|
146
146
|
t.string :title
|
147
147
|
t.string :description
|
148
148
|
end
|
149
149
|
|
150
|
-
create_table :supercats, :
|
150
|
+
create_table :supercats, force: true do |t|
|
151
151
|
t.integer :post_id
|
152
152
|
t.integer :category_id
|
153
153
|
t.string :ramblings
|
154
154
|
t.string :other_ramblings
|
155
|
-
t.timestamps
|
155
|
+
t.timestamps null: true
|
156
156
|
end
|
157
157
|
|
158
|
-
create_table :superkittens, :
|
158
|
+
create_table :superkittens, force: true do |t|
|
159
159
|
t.integer :supercat_id
|
160
160
|
t.string :value
|
161
|
-
t.timestamps
|
161
|
+
t.timestamps null: true
|
162
162
|
end
|
163
163
|
|
164
|
-
create_table :accounts, :
|
164
|
+
create_table :accounts, force: true do |t|
|
165
165
|
t.integer :post_id
|
166
166
|
t.string :title
|
167
|
-
t.timestamps
|
167
|
+
t.timestamps null: true
|
168
168
|
end
|
169
169
|
|
170
|
-
create_table :histories, :
|
170
|
+
create_table :histories, force: true do |t|
|
171
171
|
t.integer :account_id
|
172
172
|
t.string :some_stuff
|
173
|
-
t.timestamps
|
173
|
+
t.timestamps null: true
|
174
174
|
end
|
175
|
+
|
176
|
+
create_table :metal_objects, force: true do |t|
|
177
|
+
t.string :type
|
178
|
+
t.integer :parent_id
|
179
|
+
t.timestamps null: true
|
180
|
+
end
|
181
|
+
|
182
|
+
create_table :super_admins, force: true do |t|
|
183
|
+
t.string :email
|
184
|
+
t.string :password
|
185
|
+
t.boolean :active, null: false, default: true
|
186
|
+
t.timestamps null: true
|
187
|
+
end
|
188
|
+
|
189
|
+
create_table :boxes, force: true do |t|
|
190
|
+
t.string :title
|
191
|
+
t.timestamps null: true
|
192
|
+
end
|
193
|
+
|
194
|
+
create_table :box_products, force: true do |t|
|
195
|
+
t.string :type
|
196
|
+
t.integer :box_id
|
197
|
+
t.integer :box_sub_product_id
|
198
|
+
t.string :title
|
199
|
+
t.timestamps null: true
|
200
|
+
end
|
201
|
+
|
175
202
|
end
|