mongoid 4.0.0.alpha2 → 4.0.0.beta1
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 +55 -0
- data/README.md +3 -3
- data/lib/config/locales/en.yml +13 -0
- data/lib/mongoid.rb +3 -1
- data/lib/mongoid/atomic.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
- data/lib/mongoid/attributes.rb +23 -1
- data/lib/mongoid/attributes/processing.rb +1 -1
- data/lib/mongoid/composable.rb +3 -2
- data/lib/mongoid/contextual/command.rb +0 -26
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/mongo.rb +6 -29
- data/lib/mongoid/contextual/text_search.rb +3 -5
- data/lib/mongoid/criteria.rb +1 -1
- data/lib/mongoid/criteria/modifiable.rb +27 -7
- data/lib/mongoid/criteria/permission.rb +70 -0
- data/lib/mongoid/document.rb +5 -6
- data/lib/mongoid/errors.rb +2 -0
- data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
- data/lib/mongoid/errors/readonly_document.rb +24 -0
- data/lib/mongoid/extensions/boolean.rb +1 -0
- data/lib/mongoid/extensions/hash.rb +1 -1
- data/lib/mongoid/factory.rb +5 -3
- data/lib/mongoid/fields.rb +32 -0
- data/lib/mongoid/fields/localized.rb +1 -1
- data/lib/mongoid/fields/standard.rb +1 -1
- data/lib/mongoid/findable.rb +1 -0
- data/lib/mongoid/interceptable.rb +11 -6
- data/lib/mongoid/log_subscriber.rb +34 -1
- data/lib/mongoid/persistable/deletable.rb +1 -0
- data/lib/mongoid/persistable/destroyable.rb +7 -2
- data/lib/mongoid/persistable/updatable.rb +27 -26
- data/lib/mongoid/query_cache.rb +246 -0
- data/lib/mongoid/railties/database.rake +4 -26
- data/lib/mongoid/relations.rb +8 -22
- data/lib/mongoid/relations/accessors.rb +0 -3
- data/lib/mongoid/relations/binding.rb +1 -1
- data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
- data/lib/mongoid/relations/eager.rb +5 -6
- data/lib/mongoid/relations/eager/base.rb +97 -5
- data/lib/mongoid/relations/eager/belongs_to.rb +1 -0
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +16 -9
- data/lib/mongoid/relations/eager/has_many.rb +1 -0
- data/lib/mongoid/relations/eager/has_one.rb +1 -0
- data/lib/mongoid/relations/embedded/batchable.rb +1 -1
- data/lib/mongoid/relations/embedded/in.rb +4 -4
- data/lib/mongoid/relations/embedded/many.rb +7 -5
- data/lib/mongoid/relations/embedded/one.rb +1 -1
- data/lib/mongoid/relations/macros.rb +1 -0
- data/lib/mongoid/relations/marshalable.rb +3 -3
- data/lib/mongoid/relations/proxy.rb +12 -10
- data/lib/mongoid/relations/referenced/in.rb +2 -2
- data/lib/mongoid/relations/referenced/many.rb +9 -9
- data/lib/mongoid/relations/referenced/many_to_many.rb +7 -7
- data/lib/mongoid/relations/referenced/one.rb +4 -4
- data/lib/mongoid/{state.rb → stateful.rb} +13 -1
- data/lib/mongoid/tasks/database.rake +31 -0
- data/lib/mongoid/tasks/database.rb +107 -0
- data/lib/mongoid/threaded.rb +0 -47
- data/lib/mongoid/validatable/uniqueness.rb +4 -16
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +0 -3
- data/lib/rails/mongoid.rb +0 -124
- data/spec/app/models/edit.rb +5 -0
- data/spec/app/models/even.rb +7 -0
- data/spec/app/models/line_item.rb +1 -1
- data/spec/app/models/note.rb +2 -0
- data/spec/app/models/odd.rb +7 -0
- data/spec/app/models/record.rb +5 -0
- data/spec/app/models/wiki_page.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +76 -1
- data/spec/mongoid/changeable_spec.rb +6 -2
- data/spec/mongoid/contextual/mongo_spec.rb +3 -1
- data/spec/mongoid/contextual/text_search_spec.rb +3 -1
- data/spec/mongoid/criteria/modifiable_spec.rb +192 -0
- data/spec/mongoid/criteria_spec.rb +6 -2
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
- data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
- data/spec/mongoid/fields/localized_spec.rb +15 -0
- data/spec/mongoid/fields_spec.rb +88 -2
- data/spec/mongoid/log_subscriber_spec.rb +3 -3
- data/spec/mongoid/persistable/deletable_spec.rb +14 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +45 -1
- data/spec/mongoid/persistable/savable_spec.rb +34 -5
- data/spec/mongoid/query_cache_spec.rb +197 -0
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +2 -2
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +1 -1
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +11 -37
- data/spec/mongoid/relations/eager/has_one_spec.rb +1 -1
- data/spec/mongoid/relations/embedded/in_spec.rb +1 -1
- data/spec/mongoid/relations/embedded/many_spec.rb +10 -10
- data/spec/mongoid/relations/embedded/one_spec.rb +10 -2
- data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +37 -2
- data/spec/mongoid/relations/touchable_spec.rb +20 -0
- data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +26 -1
- data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
- data/spec/mongoid/tasks/database_spec.rb +148 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +7 -0
- data/spec/rails/mongoid_spec.rb +0 -316
- data/spec/spec_helper.rb +1 -0
- metadata +30 -8
@@ -0,0 +1,31 @@
|
|
1
|
+
namespace :db do
|
2
|
+
namespace :mongoid do
|
3
|
+
task :load_models do
|
4
|
+
end
|
5
|
+
|
6
|
+
desc "Create the indexes defined on your mongoid models"
|
7
|
+
task :create_indexes => [:environment, :load_models] do
|
8
|
+
::Mongoid::Tasks::Database.create_indexes
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Remove indexes that exist in the database but aren't specified on the models"
|
12
|
+
task :remove_undefined_indexes => [:environment, :load_models] do
|
13
|
+
::Mongoid::Tasks::Database.remove_undefined_indexes
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Remove the indexes defined on your mongoid models without questions!"
|
17
|
+
task :remove_indexes => [:environment, :load_models] do
|
18
|
+
::Mongoid::Tasks::Database.remove_indexes
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Drops the default session"
|
22
|
+
task :drop => :environment do
|
23
|
+
::Mongoid::Sessions.default.drop
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Drop all collections except the system collections"
|
27
|
+
task :purge => :environment do
|
28
|
+
::Mongoid.purge!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
module Tasks
|
4
|
+
module Database
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# Create indexes for each model given the provided globs and the class is
|
8
|
+
# not embedded.
|
9
|
+
#
|
10
|
+
# @example Create all the indexes.
|
11
|
+
# Mongoid::Tasks::Database.create_indexes
|
12
|
+
#
|
13
|
+
# @return [ Array<Class> ] The indexed models.
|
14
|
+
#
|
15
|
+
# @since 2.1.0
|
16
|
+
def create_indexes(models = ::Mongoid.models)
|
17
|
+
models.each do |model|
|
18
|
+
next if model.index_specifications.empty?
|
19
|
+
unless model.embedded?
|
20
|
+
model.create_indexes
|
21
|
+
logger.info("MONGOID: Created indexes on #{model}:")
|
22
|
+
model.index_specifications.each do |spec|
|
23
|
+
logger.info("MONGOID: Index: #{spec.key}, Options: #{spec.options}")
|
24
|
+
end
|
25
|
+
model
|
26
|
+
else
|
27
|
+
logger.info("MONGOID: Index ignored on: #{model}, please define in the root model.")
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end.compact
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return the list of indexes by model that exist in the database but aren't
|
34
|
+
# specified on the models.
|
35
|
+
#
|
36
|
+
# @example Return the list of unused indexes.
|
37
|
+
# Mongoid::Tasks::Database.undefined_indexes
|
38
|
+
#
|
39
|
+
# @return Hash{Class => Array(Hash)} The list of undefined indexes by model.
|
40
|
+
def undefined_indexes(models = ::Mongoid.models)
|
41
|
+
undefined_by_model = {}
|
42
|
+
|
43
|
+
models.each do |model|
|
44
|
+
unless model.embedded?
|
45
|
+
model.collection.indexes.each do |index|
|
46
|
+
# ignore default index
|
47
|
+
unless index['name'] == '_id_'
|
48
|
+
key = index['key'].symbolize_keys
|
49
|
+
spec = model.index_specification(key)
|
50
|
+
unless spec
|
51
|
+
# index not specified
|
52
|
+
undefined_by_model[model] ||= []
|
53
|
+
undefined_by_model[model] << index
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
undefined_by_model
|
61
|
+
end
|
62
|
+
|
63
|
+
# Remove indexes that exist in the database but aren't specified on the
|
64
|
+
# models.
|
65
|
+
#
|
66
|
+
# @example Remove undefined indexes.
|
67
|
+
# Mongoid::Tasks::Database.remove_undefined_indexes
|
68
|
+
#
|
69
|
+
# @return [ Hash{Class => Array(Hash)}] The list of indexes that were removed by model.
|
70
|
+
#
|
71
|
+
# @since 4.0.0
|
72
|
+
def remove_undefined_indexes(models = ::Mongoid.models)
|
73
|
+
undefined_indexes(models).each do |model, indexes|
|
74
|
+
indexes.each do |index|
|
75
|
+
key = index['key'].symbolize_keys
|
76
|
+
model.collection.indexes.drop(key)
|
77
|
+
logger.info("MONGOID: Removing index: #{index['name']} on #{model}.")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Remove indexes for each model given the provided globs and the class is
|
83
|
+
# not embedded.
|
84
|
+
#
|
85
|
+
# @example Remove all the indexes.
|
86
|
+
# Mongoid::Tasks::Database.remove_indexes
|
87
|
+
#
|
88
|
+
# @return [ Array<Class> ] The un-indexed models.
|
89
|
+
#
|
90
|
+
def remove_indexes(models = ::Mongoid.models)
|
91
|
+
models.each do |model|
|
92
|
+
next if model.embedded?
|
93
|
+
indexes = model.collection.indexes.map{ |doc| doc["name"] }
|
94
|
+
indexes.delete_one("_id_")
|
95
|
+
model.remove_indexes
|
96
|
+
logger.info("MONGOID: Removing indexes on: #{model} for: #{indexes.join(', ')}.")
|
97
|
+
model
|
98
|
+
end.compact
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def logger
|
103
|
+
@logger ||= Logger.new($stdout)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/mongoid/threaded.rb
CHANGED
@@ -150,53 +150,6 @@ module Mongoid
|
|
150
150
|
validations_for(document.class).delete_one(document.id)
|
151
151
|
end
|
152
152
|
|
153
|
-
# Get the field selection options from the current thread.
|
154
|
-
#
|
155
|
-
# @example Get the field selection options.
|
156
|
-
# Threaded.selection
|
157
|
-
#
|
158
|
-
# @param [ Integer ] criteria_instance_id The criteria instance id.
|
159
|
-
#
|
160
|
-
# @return [ Hash ] The field selection.
|
161
|
-
#
|
162
|
-
# @since 2.4.4
|
163
|
-
def selection(criteria_instance_id)
|
164
|
-
selections = Thread.current["[mongoid][selections]"]
|
165
|
-
selections[criteria_instance_id] if selections
|
166
|
-
end
|
167
|
-
|
168
|
-
# Set the field selection on the current thread.
|
169
|
-
#
|
170
|
-
# @example Set the field selection.
|
171
|
-
# Threaded.set_selection(Person, { field: 1 })
|
172
|
-
#
|
173
|
-
# @param [ Integer ] criteria_instance_id The criteria instance id.
|
174
|
-
# @param [ Hash ] value The current field selection.
|
175
|
-
#
|
176
|
-
# @return [ Hash ] The field selection.
|
177
|
-
#
|
178
|
-
# @since 2.4.4
|
179
|
-
def set_selection(criteria_instance_id, value)
|
180
|
-
Thread.current["[mongoid][selections]"] ||= {}
|
181
|
-
Thread.current["[mongoid][selections]"][criteria_instance_id] = value
|
182
|
-
end
|
183
|
-
|
184
|
-
# Delete the field selection on the current thread.
|
185
|
-
#
|
186
|
-
# @example Delete the field selection.
|
187
|
-
# Threaded.delete_selection(Person)
|
188
|
-
#
|
189
|
-
# @param [ Integer ] criteria_instance_id The criteria instance id.
|
190
|
-
#
|
191
|
-
# @return [ Boolean ] Whether there was a field selection.
|
192
|
-
#
|
193
|
-
# @since 3.0.7
|
194
|
-
def delete_selection(criteria_instance_id)
|
195
|
-
selections = Thread.current["[mongoid][selections]"]
|
196
|
-
return false unless selections
|
197
|
-
!!selections.delete(criteria_instance_id)
|
198
|
-
end
|
199
|
-
|
200
153
|
# Get the global session override.
|
201
154
|
#
|
202
155
|
# @example Get the global session override.
|
@@ -26,20 +26,6 @@ module Mongoid
|
|
26
26
|
class UniquenessValidator < ActiveModel::EachValidator
|
27
27
|
include Queryable
|
28
28
|
|
29
|
-
attr_reader :klass
|
30
|
-
|
31
|
-
# Unfortunately, we have to tie Uniqueness validators to a class.
|
32
|
-
#
|
33
|
-
# @example Setup the validator.
|
34
|
-
# UniquenessValidator.new.setup(Person)
|
35
|
-
#
|
36
|
-
# @param [ Class ] klass The class getting validated.
|
37
|
-
#
|
38
|
-
# @since 1.0.0
|
39
|
-
def setup(klass)
|
40
|
-
@klass = klass
|
41
|
-
end
|
42
|
-
|
43
29
|
# Validate the document for uniqueness violations.
|
44
30
|
#
|
45
31
|
# @example Validate the document.
|
@@ -241,7 +227,7 @@ module Mongoid
|
|
241
227
|
def to_validate(document, attribute, value)
|
242
228
|
metadata = document.relations[attribute.to_s]
|
243
229
|
if metadata && metadata.stores_foreign_key?
|
244
|
-
[ metadata.foreign_key, value.id ]
|
230
|
+
[ metadata.foreign_key, value && value.id ]
|
245
231
|
else
|
246
232
|
[ attribute, value ]
|
247
233
|
end
|
@@ -280,7 +266,9 @@ module Mongoid
|
|
280
266
|
#
|
281
267
|
# @since 2.4.10
|
282
268
|
def validate_root(document, attribute, value)
|
283
|
-
|
269
|
+
klass = document.class
|
270
|
+
klass = klass.superclass while !klass.validators.include?(self)
|
271
|
+
criteria = create_criteria(klass, document, attribute, value)
|
284
272
|
criteria = criteria.merge(options[:conditions].call) if options[:conditions]
|
285
273
|
|
286
274
|
if criteria.with(persistence_options(criteria)).exists?
|
data/lib/mongoid/version.rb
CHANGED
@@ -29,9 +29,6 @@ development:
|
|
29
29
|
# retry_interval: 1
|
30
30
|
# Configure Mongoid specific options. (optional)
|
31
31
|
options:
|
32
|
-
# Enable the identity map, needed for eager loading. (default: false)
|
33
|
-
# identity_map_enabled: false
|
34
|
-
|
35
32
|
# Includes the root model name in json serialization. (default: false)
|
36
33
|
# include_root_in_json: false
|
37
34
|
|
data/lib/rails/mongoid.rb
CHANGED
@@ -3,100 +3,6 @@ module Rails
|
|
3
3
|
module Mongoid
|
4
4
|
extend self
|
5
5
|
|
6
|
-
# Create indexes for each model given the provided globs and the class is
|
7
|
-
# not embedded.
|
8
|
-
#
|
9
|
-
# @example Create all the indexes.
|
10
|
-
# Rails::Mongoid.create_indexes
|
11
|
-
#
|
12
|
-
# @return [ Array<Class> ] The indexed models.
|
13
|
-
#
|
14
|
-
# @since 2.1.0
|
15
|
-
def create_indexes
|
16
|
-
::Mongoid.models.each do |model|
|
17
|
-
next if model.index_specifications.empty?
|
18
|
-
unless model.embedded?
|
19
|
-
model.create_indexes
|
20
|
-
logger.info("MONGOID: Created indexes on #{model}:")
|
21
|
-
model.index_specifications.each do |spec|
|
22
|
-
logger.info("MONGOID: Index: #{spec.key}, Options: #{spec.options}")
|
23
|
-
end
|
24
|
-
model
|
25
|
-
else
|
26
|
-
logger.info("MONGOID: Index ignored on: #{model}, please define in the root model.")
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
end.compact
|
30
|
-
end
|
31
|
-
|
32
|
-
# Return the list of indexes by model that exist in the database but aren't
|
33
|
-
# specified on the models.
|
34
|
-
#
|
35
|
-
# @example Return the list of unused indexes.
|
36
|
-
# Rails::Mongoid.undefined_indexes
|
37
|
-
#
|
38
|
-
# @return Hash{Class => Array(Hash)} The list of undefined indexes by model.
|
39
|
-
def undefined_indexes
|
40
|
-
undefined_by_model = {}
|
41
|
-
|
42
|
-
::Mongoid.models.each do |model|
|
43
|
-
unless model.embedded?
|
44
|
-
model.collection.indexes.each do |index|
|
45
|
-
# ignore default index
|
46
|
-
unless index['name'] == '_id_'
|
47
|
-
key = index['key'].symbolize_keys
|
48
|
-
spec = model.index_specification(key)
|
49
|
-
unless spec
|
50
|
-
# index not specified
|
51
|
-
undefined_by_model[model] ||= []
|
52
|
-
undefined_by_model[model] << index
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
undefined_by_model
|
60
|
-
end
|
61
|
-
|
62
|
-
# Remove indexes that exist in the database but aren't specified on the
|
63
|
-
# models.
|
64
|
-
#
|
65
|
-
# @example Remove undefined indexes.
|
66
|
-
# Rails::Mongoid.remove_undefined_indexes
|
67
|
-
#
|
68
|
-
# @return [ Hash{Class => Array(Hash)}] The list of indexes that were removed by model.
|
69
|
-
#
|
70
|
-
# @since 4.0.0
|
71
|
-
def remove_undefined_indexes
|
72
|
-
undefined_indexes.each do |model, indexes|
|
73
|
-
indexes.each do |index|
|
74
|
-
key = index['key'].symbolize_keys
|
75
|
-
model.collection.indexes.drop(key)
|
76
|
-
logger.info("MONGOID: Removing index: #{index['name']} on #{model}.")
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Remove indexes for each model given the provided globs and the class is
|
82
|
-
# not embedded.
|
83
|
-
#
|
84
|
-
# @example Remove all the indexes.
|
85
|
-
# Rails::Mongoid.remove_indexes
|
86
|
-
#
|
87
|
-
# @return [ Array<Class> ] The un-indexed models.
|
88
|
-
#
|
89
|
-
def remove_indexes
|
90
|
-
::Mongoid.models.each do |model|
|
91
|
-
next if model.embedded?
|
92
|
-
indexes = model.collection.indexes.map{ |doc| doc["name"] }
|
93
|
-
indexes.delete_one("_id_")
|
94
|
-
model.remove_indexes
|
95
|
-
logger.info("MONGOID: Removing indexes on: #{model} for: #{indexes.join(', ')}.")
|
96
|
-
model
|
97
|
-
end.compact
|
98
|
-
end
|
99
|
-
|
100
6
|
# Use the application configuration to get every model and require it, so
|
101
7
|
# that indexing and inheritance work in both development and production
|
102
8
|
# with the same results.
|
@@ -146,35 +52,5 @@ module Rails
|
|
146
52
|
Logger.new($stdout).warn(e.message)
|
147
53
|
end
|
148
54
|
end
|
149
|
-
|
150
|
-
# Given the provided file name, determine the model and return the class.
|
151
|
-
#
|
152
|
-
# @example Determine the model from the file.
|
153
|
-
# Rails::Mongoid.determine_model("app/models/person.rb")
|
154
|
-
#
|
155
|
-
# @param [ String ] file The filename.
|
156
|
-
#
|
157
|
-
# @return [ Class ] The model.
|
158
|
-
#
|
159
|
-
# @since 2.1.0
|
160
|
-
def determine_model(file, logger)
|
161
|
-
return nil unless file =~ /app\/models\/(.*).rb$/
|
162
|
-
return nil unless logger
|
163
|
-
|
164
|
-
model_path = $1.split('/')
|
165
|
-
begin
|
166
|
-
parts = model_path.map { |path| path.camelize }
|
167
|
-
name = parts.join("::")
|
168
|
-
klass = name.constantize
|
169
|
-
rescue NameError, LoadError
|
170
|
-
logger.info("MONGOID: Attempted to constantize #{name}, trying without namespacing.")
|
171
|
-
klass = parts.last.constantize rescue nil
|
172
|
-
end
|
173
|
-
klass if klass && klass.ancestors.include?(::Mongoid::Document)
|
174
|
-
end
|
175
|
-
|
176
|
-
def logger
|
177
|
-
@logger ||= Logger.new($stdout)
|
178
|
-
end
|
179
55
|
end
|
180
56
|
end
|
data/spec/app/models/note.rb
CHANGED
data/spec/app/models/record.rb
CHANGED
@@ -6,8 +6,8 @@ class WikiPage
|
|
6
6
|
field :transient_property, type: String
|
7
7
|
field :author, type: String
|
8
8
|
field :description, type: String, localize: true
|
9
|
-
max_versions 5
|
10
9
|
|
10
|
+
embeds_many :edits, validate: false
|
11
11
|
has_many :comments, dependent: :destroy, validate: false
|
12
12
|
has_many :child_pages, class_name: "WikiPage", dependent: :delete, inverse_of: :parent_pages
|
13
13
|
belongs_to :parent_pages, class_name: "WikiPage", inverse_of: :child_pages
|