mongoid-sleeping_king_studios 0.5.0 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/LICENSE +1 -1
- data/README.md +21 -3
- data/lib/mongoid/sleeping_king_studios.rb +11 -1
- data/lib/mongoid/sleeping_king_studios/concern.rb +69 -0
- data/lib/mongoid/sleeping_king_studios/concern/metadata.rb +61 -0
- data/lib/mongoid/sleeping_king_studios/ext/mongoid/document.rb +15 -0
- data/lib/mongoid/sleeping_king_studios/has_tree.rb +119 -68
- data/lib/mongoid/sleeping_king_studios/has_tree/cache_ancestry.rb +177 -113
- data/lib/mongoid/sleeping_king_studios/has_tree/cache_ancestry/metadata.rb +82 -0
- data/lib/mongoid/sleeping_king_studios/has_tree/children/metadata.rb +40 -0
- data/lib/mongoid/sleeping_king_studios/has_tree/errors.rb +6 -5
- data/lib/mongoid/sleeping_king_studios/has_tree/metadata.rb +64 -0
- data/lib/mongoid/sleeping_king_studios/has_tree/parent/metadata.rb +40 -0
- data/lib/mongoid/sleeping_king_studios/sluggable.rb +125 -46
- data/lib/mongoid/sleeping_king_studios/sluggable/metadata.rb +42 -0
- data/lib/mongoid/sleeping_king_studios/version.rb +2 -1
- metadata +32 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdd1c69e257d2151ecdb439fc1f9ab974628c9ba
|
4
|
+
data.tar.gz: cf273c392e0fde12e79b244819c1c880de8e11dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e20060ad75456272818d391425dad43a7deca8babe64f104a586a946221db0aa0e57d227bb16acee3ac7a3921d272a12d8da2bde3a4d2794b85a6f8233965b8
|
7
|
+
data.tar.gz: 6ab47ee0aed555756fd7ab7dadabe617985abe5c32d61efc1e4374546427abc0afebcb60185c84dfe50b87e083f8ca8ec10038120cc8480cca4adfdf7a54c8bf
|
data/CHANGELOG.md
ADDED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -54,7 +54,25 @@ Stores the chain of ancestors in an :ancestor_ids array field, and adds the
|
|
54
54
|
has_tree :cache_ancestry => true
|
55
55
|
end # class
|
56
56
|
|
57
|
-
**
|
57
|
+
**Options**
|
58
|
+
|
59
|
+
You can customize the ancestry cache by passing in a hash of options as the
|
60
|
+
:cache\_ancestry value in the ::has_tree method.
|
61
|
+
|
62
|
+
class PartGroup
|
63
|
+
include Mongoid::Document
|
64
|
+
include Mongoid::SleepingKingStudios::HasTree
|
65
|
+
|
66
|
+
# This creates the #assemblies method and #assembly_ids field.
|
67
|
+
has_tree :cache_ancestry => { :relation_name => :assemblies }
|
68
|
+
end # class
|
69
|
+
|
70
|
+
- *foreign\_key*: The name of the field used to store the ancestor references.
|
71
|
+
Defaults to 'ancestor_ids'.
|
72
|
+
- *relation\_name*: The name of the generated relation for the array of
|
73
|
+
parent objects. Defaults to 'ancestors'.
|
74
|
+
|
75
|
+
**Warning:** Using this option will make many write operations much, much
|
58
76
|
slower and more resource-intensive. Do not use this option outside of
|
59
77
|
read-heavy applications with very specific requirements, e.g. a directory
|
60
78
|
structure where you must access all parent directories on each page view.
|
@@ -83,11 +101,11 @@ short, url-friendly version.
|
|
83
101
|
|
84
102
|
slugify :title, :lockable => true
|
85
103
|
|
86
|
-
Allows the slug to be specified manually. Adds an additional slug_lock field
|
104
|
+
Allows the slug to be specified manually. Adds an additional #slug_lock field
|
87
105
|
that is automatically set to true when #slug= is called. To resume tracking the
|
88
106
|
base attribute, set :slug_lock to false.
|
89
107
|
|
90
108
|
## License
|
91
109
|
|
92
|
-
|
110
|
+
Mongoid::SleepingKingStudios is released under the
|
93
111
|
[MIT License](http://www.opensource.org/licenses/MIT).
|
@@ -1,7 +1,17 @@
|
|
1
1
|
# lib/mongoid/sleeping_king_studios.rb
|
2
2
|
|
3
3
|
require 'mongoid'
|
4
|
+
require 'sleeping_king_studios/ext/object/metaclass'
|
4
5
|
|
5
6
|
module Mongoid
|
6
|
-
|
7
|
+
# A collection of concerns and extensions to add functionality to Mongoid
|
8
|
+
# documents and collections.
|
9
|
+
module SleepingKingStudios
|
10
|
+
def self.root
|
11
|
+
Pathname.new File.join __dir__, 'sleeping_king_studios'
|
12
|
+
end # class method root
|
13
|
+
end # module
|
7
14
|
end # module
|
15
|
+
|
16
|
+
### Require Extensions ###
|
17
|
+
Dir[File.join Mongoid::SleepingKingStudios.root, *%w(ext ** *.rb)].each { |f| require f }
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# lib/mongoid/sleeping_king_studios/concern.rb
|
2
|
+
|
3
|
+
require 'mongoid/sleeping_king_studios'
|
4
|
+
require 'mongoid/sleeping_king_studios/concern/metadata'
|
5
|
+
|
6
|
+
module Mongoid::SleepingKingStudios
|
7
|
+
# Base class for concerns with shared behavior, such as creating metadata
|
8
|
+
# objects from an options hash and storing that metadata in the Document
|
9
|
+
# class's ::relations attribute.
|
10
|
+
#
|
11
|
+
# @since 0.6.0
|
12
|
+
module Concern
|
13
|
+
# @overload characterize name, properties, type = Metadata
|
14
|
+
# Creates a metadata instance for the relation.
|
15
|
+
#
|
16
|
+
# @param [Symbol] name The name of the relation. Must be unique for the
|
17
|
+
# base type within the sleeping_king_studios namespace.
|
18
|
+
# @param [Hash] options The options for the relation.
|
19
|
+
# @param [Class] type The type of the generated metadata.
|
20
|
+
#
|
21
|
+
# @return [Metadata] The generated metadata.
|
22
|
+
def characterize name, options, type = nil
|
23
|
+
type ||= Mongoid::SleepingKingStudios::Concern::Metadata
|
24
|
+
type.new name, options
|
25
|
+
end # method characterize
|
26
|
+
|
27
|
+
# Stores the metadata in the class's relations object. To avoid automatic
|
28
|
+
# Mongoid behavior on relations, adds a #sleeping_king_studios accessor to
|
29
|
+
# the relations hash by mixing in the Relations module. Then, saves the
|
30
|
+
# metadata using the metadata#relation_key as the key.
|
31
|
+
#
|
32
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
33
|
+
# @param [Symbol] name The name of the relation. Must be unique for the
|
34
|
+
# base type within the sleeping_king_studios namespace.
|
35
|
+
# @param [Metadata] metadata The metadata to be stored.
|
36
|
+
def relate base, name, metadata
|
37
|
+
base.relations_sleeping_king_studios.update metadata.relation_key => metadata
|
38
|
+
end # method relate
|
39
|
+
|
40
|
+
# Returns a list of options that are valid for this concern.
|
41
|
+
#
|
42
|
+
# @return [Array<Symbol>] The list of valid options.
|
43
|
+
def valid_options
|
44
|
+
%i(
|
45
|
+
|
46
|
+
) # end array
|
47
|
+
end # method valid_options
|
48
|
+
|
49
|
+
# Evaluates the provided options and raises an error if any of the options
|
50
|
+
# are invalid, based on the list from #valid_options.
|
51
|
+
#
|
52
|
+
# @param [Symbol] name The name of the relation.
|
53
|
+
# @param [Hash] options The options for the relation.
|
54
|
+
#
|
55
|
+
# @raise [Mongoid::Errors::InvalidOptions] If any of the options provided
|
56
|
+
# are invalid.
|
57
|
+
def validate_options name, options
|
58
|
+
options.keys.each do |key|
|
59
|
+
if !valid_options.include?(key)
|
60
|
+
raise Mongoid::Errors::InvalidOptions.new(
|
61
|
+
name,
|
62
|
+
key,
|
63
|
+
valid_options
|
64
|
+
) # end InvalidOptions
|
65
|
+
end # if
|
66
|
+
end # each
|
67
|
+
end # method validate_options
|
68
|
+
end # class
|
69
|
+
end # module
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# lib/mongoid/sleeping_king_studios/concern/metadata.rb
|
2
|
+
|
3
|
+
require 'mongoid/sleeping_king_studios'
|
4
|
+
require 'mongoid/sleeping_king_studios/concern'
|
5
|
+
|
6
|
+
module Mongoid::SleepingKingStudios
|
7
|
+
module Concern
|
8
|
+
# Stores information about a given concern or relation. By default, stored
|
9
|
+
# in the Document class's ::relations attribute. Concerns may subclass
|
10
|
+
# Metadata to add further keys and/or functionality.
|
11
|
+
#
|
12
|
+
# @since 0.6.0
|
13
|
+
class Metadata < Hash
|
14
|
+
# @param [Symbol, String] name The name of the concern or relation.
|
15
|
+
# @param [Hash] properties The properties of the concern or relation.
|
16
|
+
def initialize name, properties = {}
|
17
|
+
@name = name
|
18
|
+
@properties = properties.dup
|
19
|
+
|
20
|
+
merge! properties if Hash === properties
|
21
|
+
end # method initialize
|
22
|
+
|
23
|
+
# @return [Symbol] The name of the concern or relation.
|
24
|
+
attr_reader :name
|
25
|
+
|
26
|
+
# @return [Hash] The unmodified properties hash that was passed into the
|
27
|
+
# constructor.
|
28
|
+
attr_reader :properties
|
29
|
+
|
30
|
+
# @overload characterize name, properties, type = Metadata
|
31
|
+
# Creates a metadata instance for a subgroup of the metadata, such as a
|
32
|
+
# generated relation or for an optional parameter.
|
33
|
+
#
|
34
|
+
# @param [Symbol] name The name of the relation. Must be unique for the
|
35
|
+
# base type within the sleeping_king_studios namespace.
|
36
|
+
# @param [Hash] properties The options for the relation.
|
37
|
+
# @param [Class] type The type of the generated metadata.
|
38
|
+
#
|
39
|
+
# @return [Metadata] The generated metadata.
|
40
|
+
def characterize name, properties, type = nil
|
41
|
+
type ||= Mongoid::SleepingKingStudios::Concern::Metadata
|
42
|
+
type.new name, properties
|
43
|
+
end # method characterize
|
44
|
+
|
45
|
+
# The key used to store the metadata inside the class's ::relations
|
46
|
+
# attribute. By default, adds the prefix 'sleeping_king_studios::' to the
|
47
|
+
# name, but can be set via the properties hash.
|
48
|
+
#
|
49
|
+
# @return [String] The key used to store the metadata.
|
50
|
+
def relation_key
|
51
|
+
self[:relation_key] || name.to_s
|
52
|
+
end # method relation_key
|
53
|
+
|
54
|
+
# @return [Boolean] True if a custom relation key is defined, otherwise
|
55
|
+
# false.
|
56
|
+
def relation_key?
|
57
|
+
!!self[:relation_key]
|
58
|
+
end # method relation_key?
|
59
|
+
end # class
|
60
|
+
end # module
|
61
|
+
end # module
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# lib/mongoid/sleeping_king_studios/ext/mongoid/document.rb
|
2
|
+
|
3
|
+
require 'mongoid'
|
4
|
+
|
5
|
+
module Mongoid
|
6
|
+
module Document
|
7
|
+
module ClassMethods
|
8
|
+
# Metadata for the relations and concerns on the document class in the
|
9
|
+
# Mongoid::SleepingKingStudios namespace.
|
10
|
+
def relations_sleeping_king_studios
|
11
|
+
@relations_sleeping_king_studios ||= {}
|
12
|
+
end # class method relations_sleeping_king_studios
|
13
|
+
end # module
|
14
|
+
end # module
|
15
|
+
end # module
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# lib/mongoid/sleeping_king_studios/tree.rb
|
2
2
|
|
3
3
|
require 'mongoid/sleeping_king_studios'
|
4
|
+
require 'mongoid/sleeping_king_studios/concern'
|
5
|
+
require 'mongoid/sleeping_king_studios/has_tree/metadata'
|
4
6
|
require 'mongoid/sleeping_king_studios/has_tree/cache_ancestry'
|
5
7
|
|
6
8
|
module Mongoid::SleepingKingStudios
|
@@ -34,6 +36,98 @@ module Mongoid::SleepingKingStudios
|
|
34
36
|
# @since 0.2.0
|
35
37
|
module HasTree
|
36
38
|
extend ActiveSupport::Concern
|
39
|
+
extend Mongoid::SleepingKingStudios::Concern
|
40
|
+
|
41
|
+
# @api private
|
42
|
+
#
|
43
|
+
# Sets up the has_tree relation, creating fields, accessors and
|
44
|
+
# validations.
|
45
|
+
#
|
46
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
47
|
+
# @param [Hash] options The options for the relation.
|
48
|
+
#
|
49
|
+
# @since 0.6.0
|
50
|
+
def self.apply base, options
|
51
|
+
options[:parent] ||= {}
|
52
|
+
options[:children] ||= {}
|
53
|
+
|
54
|
+
options[:parent][:inverse_of] = options[:children].fetch(:relation_name, :children)
|
55
|
+
options[:children][:inverse_of] = options[:parent].fetch(:relation_name, :parent)
|
56
|
+
|
57
|
+
name = :has_tree
|
58
|
+
validate_options name, options
|
59
|
+
meta = characterize name, options, Metadata
|
60
|
+
|
61
|
+
relate base, name, meta
|
62
|
+
|
63
|
+
define_relations base, meta
|
64
|
+
define_helpers base, meta
|
65
|
+
|
66
|
+
if meta.cache_ancestry?
|
67
|
+
concern = Mongoid::SleepingKingStudios::HasTree::CacheAncestry
|
68
|
+
concern.send :apply, base, meta.cache_ancestry
|
69
|
+
end # if
|
70
|
+
end # class method apply
|
71
|
+
|
72
|
+
# @api private
|
73
|
+
#
|
74
|
+
# Sets up the helper methods for the relations as follows.
|
75
|
+
#
|
76
|
+
# Defines the following class methods:
|
77
|
+
# - ::roots
|
78
|
+
#
|
79
|
+
# Defines the following instance methods:
|
80
|
+
# - #leaf?
|
81
|
+
# - #root
|
82
|
+
# - #root?
|
83
|
+
#
|
84
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
85
|
+
# @param [Metadata] metadata The metadata for the relation.
|
86
|
+
#
|
87
|
+
# @since 0.6.0
|
88
|
+
def self.define_helpers base, metadata
|
89
|
+
base.metaclass.send :define_method, :roots do
|
90
|
+
where({ :"#{metadata.parent.relation_name}_id" => nil })
|
91
|
+
end # class method roots
|
92
|
+
|
93
|
+
base.send :define_method, :root do
|
94
|
+
parent = send(metadata.parent.relation_name)
|
95
|
+
parent ? parent.root : self
|
96
|
+
end # method root
|
97
|
+
|
98
|
+
base.send :define_method, :leaf? do
|
99
|
+
send(metadata.children.relation_name).blank?
|
100
|
+
end # method root?
|
101
|
+
|
102
|
+
base.send :define_method, :root? do
|
103
|
+
send(metadata.parent.relation_name).nil?
|
104
|
+
end # method root?
|
105
|
+
|
106
|
+
base.send :define_method, :siblings do
|
107
|
+
self.class.where(:id => { "$ne" => self.id }).where(metadata.foreign_key => self.send(metadata.foreign_key))
|
108
|
+
end # method siblings
|
109
|
+
end # class method define_helpers
|
110
|
+
|
111
|
+
# @api private
|
112
|
+
#
|
113
|
+
# Sets up the parent and children relations.
|
114
|
+
#
|
115
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
116
|
+
# @param [Metadata] metadata The metadata for the relation.
|
117
|
+
#
|
118
|
+
# @since 0.6.0
|
119
|
+
def self.define_relations base, metadata
|
120
|
+
parent_options = metadata.parent.properties.dup
|
121
|
+
parent_options.update :class_name => base.name
|
122
|
+
parent_options.delete :relation_name
|
123
|
+
|
124
|
+
children_options = metadata.children.properties.dup
|
125
|
+
children_options.update :class_name => base.name
|
126
|
+
children_options.delete :relation_name
|
127
|
+
|
128
|
+
base.belongs_to metadata.parent.relation_name, parent_options
|
129
|
+
base.has_many metadata.children.relation_name, children_options
|
130
|
+
end # class method define_relations
|
37
131
|
|
38
132
|
# Get the valid options allowed with this concern.
|
39
133
|
#
|
@@ -77,93 +171,50 @@ module Mongoid::SleepingKingStudios
|
|
77
171
|
# ancestors in an :ancestor_ids array field. Adds the #ancestors and
|
78
172
|
# #descendents scopes.
|
79
173
|
#
|
80
|
-
# Warning:
|
174
|
+
# Warning: Using this option will make many write operations much,
|
81
175
|
# much slower and more resource-intensive. Do not use this option
|
82
176
|
# outside of read-heavy applications with very specific requirements,
|
83
177
|
# e.g. a directory structure where you must access all parent
|
84
178
|
# directories on each page view.
|
85
179
|
#
|
86
|
-
# @see Mongoid::SleepingKingStudios::HasTree::CacheAncestry
|
180
|
+
# @see Mongoid::SleepingKingStudios::HasTree::CacheAncestry::ClassMethods#cache_ancestry
|
87
181
|
#
|
88
182
|
# @raise [ Mongoid::Errors::InvalidOptions ] If the options are invalid.
|
89
183
|
#
|
90
184
|
# @since 0.4.0
|
91
185
|
def has_tree **options
|
92
|
-
|
93
|
-
|
94
|
-
# Create Relations
|
95
|
-
p_opts = { :relation_name => :parent, :class_name => self.name }
|
96
|
-
c_opts = { :relation_name => :children, :class_name => self.name }
|
97
|
-
|
98
|
-
p_opts.update(options[:parent]) if Hash === options[:parent]
|
99
|
-
c_opts.update(options[:children]) if Hash === options[:children]
|
100
|
-
|
101
|
-
p_opts.update :inverse_of => c_opts[:relation_name]
|
102
|
-
c_opts.update :inverse_of => p_opts[:relation_name]
|
103
|
-
|
104
|
-
belongs_to p_opts.delete(:relation_name), p_opts
|
105
|
-
has_many c_opts.delete(:relation_name), c_opts
|
106
|
-
|
107
|
-
options[:parent] = p_opts
|
108
|
-
options[:children] = c_opts
|
109
|
-
|
110
|
-
# Set Up Ancestry Cache
|
111
|
-
if options.has_key? :cache_ancestry
|
112
|
-
self.send :include, Mongoid::SleepingKingStudios::HasTree::CacheAncestry
|
113
|
-
self.send :cache_ancestry, **options
|
114
|
-
end # if
|
115
|
-
|
116
|
-
self
|
186
|
+
concern = Mongoid::SleepingKingStudios::HasTree
|
187
|
+
concern.apply self, options
|
117
188
|
end # class method has_tree
|
118
189
|
|
119
|
-
#
|
120
|
-
#
|
190
|
+
# @!method roots
|
191
|
+
# Returns a Criteria specifying all root objects, e.g. objects with no
|
192
|
+
# parent object.
|
121
193
|
#
|
122
|
-
#
|
123
|
-
def roots
|
124
|
-
where({ :parent_id => nil })
|
125
|
-
end # scope routes
|
126
|
-
|
127
|
-
private
|
128
|
-
|
129
|
-
# Determine if the provided options are valid for the concern.
|
130
|
-
#
|
131
|
-
# @param [ Hash ] options The options to check.
|
132
|
-
#
|
133
|
-
# @raise [ Mongoid::Errors::InvalidOptions ] If the options are invalid.
|
134
|
-
def validate_options options
|
135
|
-
valid_options = Mongoid::SleepingKingStudios::HasTree.valid_options
|
136
|
-
options.keys.each do |key|
|
137
|
-
if !valid_options.include?(key)
|
138
|
-
raise Mongoid::Errors::InvalidOptions.new(
|
139
|
-
:has_tree,
|
140
|
-
key,
|
141
|
-
valid_options
|
142
|
-
) # end InvalidOptions
|
143
|
-
end # if
|
144
|
-
end # each
|
145
|
-
end # class method validate_options
|
194
|
+
# @return [Mongoid::Criteria]
|
146
195
|
end # module
|
147
196
|
|
148
|
-
#
|
197
|
+
# @!method root
|
198
|
+
# Returns the root object of the current object's tree.
|
149
199
|
#
|
150
|
-
#
|
151
|
-
def root
|
152
|
-
parent ? parent.root : self
|
153
|
-
end # method root
|
200
|
+
# @return [Tree]
|
154
201
|
|
155
|
-
#
|
202
|
+
# @!method leaf?
|
203
|
+
# Returns true if the object is a leaf object, e.g. has no child objects.
|
156
204
|
#
|
157
|
-
#
|
158
|
-
def leaf?
|
159
|
-
children.empty?
|
160
|
-
end # method leaf?
|
205
|
+
# @return [Boolean] True if the object has no children; otherwise false.
|
161
206
|
|
162
|
-
#
|
207
|
+
# @!method root?
|
208
|
+
# Returns true if the object is a root object, e.g. has no parent object.
|
209
|
+
#
|
210
|
+
# @return [Boolean] True if the object has no parent; otherwise false.
|
211
|
+
|
212
|
+
# @!method siblings
|
213
|
+
# Returns a Criteria specifying all persisted objects in the tree whose
|
214
|
+
# parent is the current object's parent, excluding the current object.
|
215
|
+
#
|
216
|
+
# @return [Mongoid::Criteria]
|
163
217
|
#
|
164
|
-
#
|
165
|
-
def root?
|
166
|
-
parent.nil?
|
167
|
-
end # method root?
|
218
|
+
# @since 0.6.1
|
168
219
|
end # module
|
169
220
|
end # module
|