amoeba 3.4.0 → 3.4.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/amoeba/cloner.rb +2 -0
- data/lib/amoeba/macros.rb +1 -0
- data/lib/amoeba/version.rb +1 -1
- metadata +14 -93
- data/.cane +0 -4
- data/.github/workflows/activerecord_head.yml +0 -26
- data/.github/workflows/jruby.yml +0 -30
- data/.github/workflows/rspec.yml +0 -49
- data/.github/workflows/rubocop.yml +0 -20
- data/.gitignore +0 -10
- data/.rspec +0 -2
- data/.rubocop.yml +0 -21
- data/.rubocop_todo.yml +0 -149
- data/Appraisals +0 -69
- data/Gemfile +0 -16
- data/Rakefile +0 -8
- data/amoeba.gemspec +0 -40
- data/defaults.reek +0 -11
- data/gemfiles/activerecord_6.1.gemfile +0 -27
- data/gemfiles/activerecord_7.0.gemfile +0 -22
- data/gemfiles/activerecord_7.1.gemfile +0 -21
- data/gemfiles/activerecord_8.0.gemfile +0 -21
- data/gemfiles/activerecord_8.1.gemfile +0 -21
- data/gemfiles/activerecord_head.gemfile +0 -23
- data/gemfiles/jruby_activerecord_7.0.gemfile +0 -20
- data/gemfiles/jruby_activerecord_head.gemfile +0 -28
- data/spec/lib/amoeba_spec.rb +0 -598
- data/spec/spec_helper.rb +0 -39
- data/spec/support/data.rb +0 -108
- data/spec/support/models.rb +0 -425
- data/spec/support/schema.rb +0 -237
data/spec/support/data.rb
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
u1 = User.create(name: 'Robert Johnson', email: 'bob@crossroads.com')
|
|
4
|
-
u2 = User.create(name: 'Miles Davis', email: 'miles@kindofblue.com')
|
|
5
|
-
|
|
6
|
-
a1 = Author.create(full_name: 'Kermit The Vonnegut', nickname: 'kvsoitgoes')
|
|
7
|
-
a2 = Author.create(full_name: 'Arthur Sees Clarck', nickname: 'strangewater')
|
|
8
|
-
|
|
9
|
-
t = Topic.create(title: 'Ponies', description: 'Lets talk about my ponies.')
|
|
10
|
-
|
|
11
|
-
# First Post {{{
|
|
12
|
-
p1 = t.posts.create(owner: u1, author: a1, title: 'My little pony',
|
|
13
|
-
contents: 'Lorum ipsum dolor rainbow bright. I like dogs, dogs are awesome.')
|
|
14
|
-
f1 = p1.create_post_config(is_visible: true, is_open: false, password: 'abcdefg123')
|
|
15
|
-
a1 = p1.create_account(title: 'Foo')
|
|
16
|
-
h1 = p1.account.create_history(some_stuff: 'Bar')
|
|
17
|
-
c1 = p1.comments.create(contents: 'I love it!', nerf: 'ratatat')
|
|
18
|
-
[5, 5, 4, 3, 5, 5].each { |stars| c1.ratings.create(num_stars: stars) }
|
|
19
|
-
|
|
20
|
-
c2 = p1.comments.create(contents: 'I hate it!', nerf: 'whapaow')
|
|
21
|
-
[3, 1, 4, 1, 1, 2].each { |stars| c2.ratings.create(num_stars: stars) }
|
|
22
|
-
|
|
23
|
-
c3 = p1.comments.create(contents: 'kthxbbq!!11!!!1!eleven!!', nerf: 'bonk')
|
|
24
|
-
[0, 0, 1, 2, 1, 0].each { |stars| c3.ratings.create(num_stars: stars) }
|
|
25
|
-
|
|
26
|
-
%w[funny wtf cats].each { |value| p1.tags << Tag.create(value: value) }
|
|
27
|
-
|
|
28
|
-
['My Sidebar', 'Photo Gallery', 'Share & Like'].each do |value|
|
|
29
|
-
p1.widgets << Widget.create(value: value)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
['This is important', "You've been warned", "Don't forget"].each do |value|
|
|
33
|
-
p1.notes << Note.create(value: value)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
p1.save
|
|
37
|
-
|
|
38
|
-
c1 = Category.create(title: 'Umbrellas', description: 'Clown fart')
|
|
39
|
-
c2 = Category.create(title: 'Widgets', description: 'Humpty dumpty')
|
|
40
|
-
c3 = Category.create(title: 'Wombats', description: 'Slushy mushy')
|
|
41
|
-
|
|
42
|
-
s1 = Supercat.create(post: p1, category: c1, ramblings: 'zomg', other_ramblings: 'nerp')
|
|
43
|
-
s2 = Supercat.create(post: p1, category: c2, ramblings: 'why', other_ramblings: 'narp')
|
|
44
|
-
s3 = Supercat.create(post: p1, category: c3, ramblings: 'ohnoes', other_ramblings: 'blap')
|
|
45
|
-
|
|
46
|
-
s1.superkittens.create(value: 'Fluffy')
|
|
47
|
-
s1.superkittens.create(value: 'Buffy')
|
|
48
|
-
s1.superkittens.create(value: 'Fuzzy')
|
|
49
|
-
|
|
50
|
-
s2.superkittens.create(value: 'Hairball')
|
|
51
|
-
s2.superkittens.create(value: 'Crosseye')
|
|
52
|
-
s2.superkittens.create(value: 'Spot')
|
|
53
|
-
|
|
54
|
-
s3.superkittens.create(value: 'Dopey')
|
|
55
|
-
s3.superkittens.create(value: 'Sneezy')
|
|
56
|
-
s3.superkittens.create(value: 'Sleepy')
|
|
57
|
-
|
|
58
|
-
p1.custom_things.create([{ value: [1, 2] }, { value: [] }, { value: [78] }])
|
|
59
|
-
# }}}
|
|
60
|
-
|
|
61
|
-
# Product {{{
|
|
62
|
-
product1 = Product.create(title: 'Sticky Notes 5-Pak', price: 5.99, weight: 0.56)
|
|
63
|
-
shirt1 = Shirt.create(title: 'Fancy Shirt', price: 48.95, sleeve: 32, collar: 15.5)
|
|
64
|
-
necklace1 = Necklace.create(title: 'Pearl Necklace', price: 2995.99, length: 18, metal: '14k')
|
|
65
|
-
|
|
66
|
-
img1 = product1.images.create(filename: 'sticky.jpg')
|
|
67
|
-
img2 = product1.images.create(filename: 'notes.jpg')
|
|
68
|
-
|
|
69
|
-
img1 = shirt1.images.create(filename: '02948u31.jpg')
|
|
70
|
-
img2 = shirt1.images.create(filename: 'zsif8327.jpg')
|
|
71
|
-
|
|
72
|
-
img1 = necklace1.images.create(filename: 'ae02x9f1.jpg')
|
|
73
|
-
img2 = necklace1.images.create(filename: 'cba9f912.jpg')
|
|
74
|
-
|
|
75
|
-
office = Section.create(name: 'Office', num_employees: 2, total_sales: '1234.56')
|
|
76
|
-
supplies = Section.create(name: 'Supplies', num_employees: 1, total_sales: '543.21')
|
|
77
|
-
mens = Section.create(name: 'Mens', num_employees: 3, total_sales: '11982.63')
|
|
78
|
-
apparel = Section.create(name: 'Apparel', num_employees: 5, total_sales: '1315.20')
|
|
79
|
-
accessories = Section.create(name: 'Accessories', num_employees: 1, total_sales: '8992.34')
|
|
80
|
-
jewelry = Section.create(name: 'Jewelry', num_employees: 3, total_sales: '25481.77')
|
|
81
|
-
|
|
82
|
-
product1.sections << office
|
|
83
|
-
product1.sections << supplies
|
|
84
|
-
product1.save
|
|
85
|
-
|
|
86
|
-
shirt1.sections << mens
|
|
87
|
-
shirt1.sections << apparel
|
|
88
|
-
shirt1.save
|
|
89
|
-
|
|
90
|
-
necklace1.sections << jewelry
|
|
91
|
-
necklace1.sections << accessories
|
|
92
|
-
necklace1.save
|
|
93
|
-
|
|
94
|
-
company = Company.create(name: 'ABC Industries')
|
|
95
|
-
employee = company.employees.create(name: 'Joe', ssn: '1111111111', salary: 10_000.0)
|
|
96
|
-
employee_address = employee.addresses.create(street: '123 My Street', unit: '103', city: 'Hollywood',
|
|
97
|
-
state: 'CA', zip: '90210')
|
|
98
|
-
employee_address_2 = employee.addresses.create(street: '124 My Street', unit: '103', city: 'Follywood',
|
|
99
|
-
state: 'CA', zip: '90210')
|
|
100
|
-
employee_photo = employee.photos.create(name: 'Portrait', size: 12_345)
|
|
101
|
-
customer = company.customers.create(email: 'my@email.address', password: 'password')
|
|
102
|
-
customer_address = customer.addresses.create(street: '321 My Street', unit: '301', city: 'Bollywood',
|
|
103
|
-
state: 'IN', zip: '11111')
|
|
104
|
-
customer_address_2 = customer.addresses.create(street: '321 My Drive', unit: '311', city: 'Mollywood',
|
|
105
|
-
state: 'IN', zip: '21111')
|
|
106
|
-
customer_photo = customer.photos.create(name: 'Mug Shot', size: 54_321)
|
|
107
|
-
|
|
108
|
-
# }}}
|
data/spec/support/models.rb
DELETED
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class Topic < ActiveRecord::Base
|
|
4
|
-
has_many :posts
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
class User < ActiveRecord::Base
|
|
8
|
-
has_many :posts
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
class Author < ActiveRecord::Base
|
|
12
|
-
has_many :posts, inverse_of: :author
|
|
13
|
-
amoeba do
|
|
14
|
-
enable
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
class Post < ActiveRecord::Base
|
|
19
|
-
belongs_to :topic
|
|
20
|
-
belongs_to :owner, class_name: 'User'
|
|
21
|
-
belongs_to :author, inverse_of: :posts
|
|
22
|
-
has_one :post_config
|
|
23
|
-
has_one :account
|
|
24
|
-
has_one :history, through: :account
|
|
25
|
-
has_many :comments
|
|
26
|
-
has_many :supercats
|
|
27
|
-
has_many :categories, through: :supercats
|
|
28
|
-
has_many :post_widgets
|
|
29
|
-
has_many :widgets, through: :post_widgets
|
|
30
|
-
has_many :custom_things
|
|
31
|
-
has_and_belongs_to_many :tags
|
|
32
|
-
has_and_belongs_to_many :notes
|
|
33
|
-
|
|
34
|
-
validates_presence_of :topic
|
|
35
|
-
validates_presence_of :author
|
|
36
|
-
|
|
37
|
-
amoeba do
|
|
38
|
-
enable
|
|
39
|
-
clone %i[widgets notes]
|
|
40
|
-
prepend title: 'Copy of '
|
|
41
|
-
append contents: ' (copied version)'
|
|
42
|
-
regex contents: { replace: /dog/, with: 'cat' }
|
|
43
|
-
customize([
|
|
44
|
-
lambda do |orig_obj, copy_of_obj|
|
|
45
|
-
orig_obj.comments.each do |oc|
|
|
46
|
-
next unless oc.nerf == 'ratatat'
|
|
47
|
-
|
|
48
|
-
hash = oc.attributes
|
|
49
|
-
hash[:id] = nil
|
|
50
|
-
hash[:post_id] = nil
|
|
51
|
-
hash[:contents] = nil
|
|
52
|
-
|
|
53
|
-
cc = Comment.new(hash)
|
|
54
|
-
|
|
55
|
-
copy_of_obj.comments << cc
|
|
56
|
-
end
|
|
57
|
-
end,
|
|
58
|
-
lambda do |orig_obj, copy_of_obj|
|
|
59
|
-
orig_obj.comments.each do |oc|
|
|
60
|
-
next unless oc.nerf == 'bonk'
|
|
61
|
-
|
|
62
|
-
hash = oc.attributes
|
|
63
|
-
hash[:id] = nil
|
|
64
|
-
hash[:post_id] = nil
|
|
65
|
-
hash[:contents] = nil
|
|
66
|
-
hash[:nerf] = 'bonkers'
|
|
67
|
-
|
|
68
|
-
cc = Comment.new(hash)
|
|
69
|
-
|
|
70
|
-
copy_of_obj.comments << cc
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
])
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def truthy?
|
|
77
|
-
true
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def falsey?
|
|
81
|
-
false
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
class << self
|
|
85
|
-
def tag_count
|
|
86
|
-
ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS tag_count FROM posts_tags')['tag_count']
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def note_count
|
|
90
|
-
ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS note_count FROM notes_posts')['note_count']
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
class CustomThing < ActiveRecord::Base
|
|
96
|
-
belongs_to :post
|
|
97
|
-
|
|
98
|
-
class ArrayPack
|
|
99
|
-
def self.load(str)
|
|
100
|
-
return [] unless str.present?
|
|
101
|
-
return str if str.is_a?(Array)
|
|
102
|
-
|
|
103
|
-
str.split(',').map(&:to_i)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def self.dump(int_array)
|
|
107
|
-
return '' unless int_array.present?
|
|
108
|
-
|
|
109
|
-
int_array.join(',')
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
serialize :value, coder: ArrayPack
|
|
114
|
-
|
|
115
|
-
before_create :hydrate_me
|
|
116
|
-
|
|
117
|
-
def hydrate_me
|
|
118
|
-
self.value = value
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
class Account < ActiveRecord::Base
|
|
123
|
-
belongs_to :post
|
|
124
|
-
has_one :history
|
|
125
|
-
|
|
126
|
-
amoeba do
|
|
127
|
-
enable
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
class History < ActiveRecord::Base
|
|
132
|
-
belongs_to :account
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
class Category < ActiveRecord::Base
|
|
136
|
-
has_many :supercats
|
|
137
|
-
has_many :posts, through: :supercats
|
|
138
|
-
|
|
139
|
-
amoeba do
|
|
140
|
-
enable
|
|
141
|
-
prepend ramblings: 'Copy of '
|
|
142
|
-
set other_ramblings: 'La la la'
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
class Supercat < ActiveRecord::Base
|
|
147
|
-
belongs_to :post
|
|
148
|
-
belongs_to :category
|
|
149
|
-
has_many :superkittens
|
|
150
|
-
|
|
151
|
-
amoeba do
|
|
152
|
-
include_association :superkittens
|
|
153
|
-
prepend ramblings: 'Copy of '
|
|
154
|
-
set other_ramblings: 'La la la'
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
class Superkitten < ActiveRecord::Base
|
|
159
|
-
belongs_to :supercat
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
class PostConfig < ActiveRecord::Base
|
|
163
|
-
belongs_to :post
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
class Comment < ActiveRecord::Base
|
|
167
|
-
belongs_to :post
|
|
168
|
-
has_many :ratings
|
|
169
|
-
has_many :reviews
|
|
170
|
-
|
|
171
|
-
amoeba do
|
|
172
|
-
exclude_association :reviews
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
class Review < ActiveRecord::Base
|
|
177
|
-
belongs_to :comment
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
class Rating < ActiveRecord::Base
|
|
181
|
-
belongs_to :comment
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
class Widget < ActiveRecord::Base
|
|
185
|
-
has_many :post_widgets
|
|
186
|
-
has_many :posts, through: :post_widgets
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
class PostWidget < ActiveRecord::Base
|
|
190
|
-
belongs_to :post
|
|
191
|
-
belongs_to :widget
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
class Tag < ActiveRecord::Base
|
|
195
|
-
has_and_belongs_to_many :posts
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
class Note < ActiveRecord::Base
|
|
199
|
-
has_and_belongs_to_many :posts
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# Inheritance
|
|
203
|
-
class Product < ActiveRecord::Base
|
|
204
|
-
has_many :images
|
|
205
|
-
has_and_belongs_to_many :sections
|
|
206
|
-
|
|
207
|
-
SECTION_COUNT_QUERY = 'SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?'
|
|
208
|
-
|
|
209
|
-
amoeba do
|
|
210
|
-
enable
|
|
211
|
-
propagate
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def section_count
|
|
215
|
-
ActiveRecord::Base.connection.select_one(SECTION_COUNT_QUERY, id)['section_count']
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
class Section < ActiveRecord::Base
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
class Image < ActiveRecord::Base
|
|
223
|
-
def truthy?
|
|
224
|
-
true
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
def falsey?
|
|
228
|
-
false
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
class Shirt < Product
|
|
233
|
-
amoeba do
|
|
234
|
-
raised :submissive
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
class Necklace < Product
|
|
239
|
-
# Strange bug on rbx
|
|
240
|
-
if defined?(::Rubinius)
|
|
241
|
-
after_initialize :set_type
|
|
242
|
-
|
|
243
|
-
def set_type
|
|
244
|
-
self.type = 'Necklace'
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
amoeba do
|
|
249
|
-
raised :relaxed
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
class BlackBox < Product
|
|
254
|
-
amoeba do
|
|
255
|
-
propagate :strict
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
class SuperBlackBox < BlackBox
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
# Polymorphism
|
|
263
|
-
class Address < ActiveRecord::Base
|
|
264
|
-
belongs_to :addressable, polymorphic: true
|
|
265
|
-
|
|
266
|
-
amoeba do
|
|
267
|
-
enable
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
class Photo < ActiveRecord::Base
|
|
272
|
-
belongs_to :imageable, polymorphic: true
|
|
273
|
-
|
|
274
|
-
amoeba do
|
|
275
|
-
customize(lambda { |original_photo, new_photo|
|
|
276
|
-
new_photo.name = original_photo.name.to_s + ' Copy'
|
|
277
|
-
})
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
class Company < ActiveRecord::Base
|
|
282
|
-
has_many :employees
|
|
283
|
-
has_many :customers
|
|
284
|
-
|
|
285
|
-
amoeba do
|
|
286
|
-
include_associations :employees,
|
|
287
|
-
:customers
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
class Employee < ActiveRecord::Base
|
|
292
|
-
has_many :addresses, as: :addressable
|
|
293
|
-
has_many :photos, as: :imageable
|
|
294
|
-
belongs_to :company
|
|
295
|
-
|
|
296
|
-
amoeba do
|
|
297
|
-
include_associations %i[addresses photos]
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
class Customer < ActiveRecord::Base
|
|
302
|
-
has_many :addresses, as: :addressable
|
|
303
|
-
has_many :photos, as: :imageable
|
|
304
|
-
belongs_to :company
|
|
305
|
-
|
|
306
|
-
amoeba do
|
|
307
|
-
enable
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
# Remapping and Method
|
|
312
|
-
|
|
313
|
-
class MetalObject < ActiveRecord::Base
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
class ObjectPrototype < MetalObject
|
|
317
|
-
has_many :subobject_prototypes, foreign_key: :parent_id
|
|
318
|
-
|
|
319
|
-
amoeba do
|
|
320
|
-
enable
|
|
321
|
-
through :become_real
|
|
322
|
-
remapper :remap_subobjects
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
def become_real
|
|
326
|
-
dup.becomes RealObject
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
def remap_subobjects(relation_name)
|
|
330
|
-
:subobjects if relation_name == :subobject_prototypes
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
class RealObject < MetalObject
|
|
335
|
-
has_many :subobjects, foreign_key: :parent_id
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
class SubobjectPrototype < MetalObject
|
|
339
|
-
amoeba do
|
|
340
|
-
enable
|
|
341
|
-
through :become_subobject
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
def become_subobject
|
|
345
|
-
dup.becomes Subobject
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
class Subobject < MetalObject
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
# Check of changing boolean attributes
|
|
353
|
-
|
|
354
|
-
class SuperAdmin < ::ActiveRecord::Base
|
|
355
|
-
amoeba do
|
|
356
|
-
set active: false
|
|
357
|
-
prepend password: false
|
|
358
|
-
end
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
# Proper inheritance
|
|
362
|
-
|
|
363
|
-
class Box < ActiveRecord::Base
|
|
364
|
-
has_many :products, class_name: 'BoxProduct'
|
|
365
|
-
has_many :sub_products, class_name: 'BoxSubProduct'
|
|
366
|
-
|
|
367
|
-
amoeba do
|
|
368
|
-
enable
|
|
369
|
-
end
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
class BoxProduct < ActiveRecord::Base
|
|
373
|
-
belongs_to :box, class_name: 'Box'
|
|
374
|
-
|
|
375
|
-
amoeba do
|
|
376
|
-
enable
|
|
377
|
-
propagate
|
|
378
|
-
end
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
class BoxSubProduct < BoxProduct
|
|
382
|
-
has_one :another_product, class_name: 'BoxAnotherProduct'
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
class BoxSubSubProduct < BoxSubProduct
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
class BoxAnotherProduct < BoxProduct
|
|
389
|
-
belongs_to :sub_product, class_name: 'BoxSubProduct'
|
|
390
|
-
end
|
|
391
|
-
|
|
392
|
-
# Inclusion inheritance
|
|
393
|
-
class Stage < ActiveRecord::Base
|
|
394
|
-
has_many :listeners
|
|
395
|
-
has_many :specialists
|
|
396
|
-
|
|
397
|
-
amoeba do
|
|
398
|
-
include_association :listeners
|
|
399
|
-
include_association :specialists
|
|
400
|
-
nullify :external_id
|
|
401
|
-
propagate
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
class Participant < ActiveRecord::Base
|
|
406
|
-
belongs_to :stage
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
class Listener < Participant
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
class Specialist < Participant
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
class CustomStage < Stage
|
|
416
|
-
has_many :custom_rules, foreign_key: :stage_id
|
|
417
|
-
|
|
418
|
-
amoeba do
|
|
419
|
-
include_association :custom_rules
|
|
420
|
-
end
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
class CustomRule < ActiveRecord::Base
|
|
424
|
-
belongs_to :custom_stage
|
|
425
|
-
end
|