mongoid-sleeping_king_studios 0.5.0 → 0.6.2
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 +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
|