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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc9bfc29b8eaf26a12fdf6e8779468794c67d352
4
- data.tar.gz: a927885e26c3aa375696654acc8d412b96ecc5b6
3
+ metadata.gz: fdd1c69e257d2151ecdb439fc1f9ab974628c9ba
4
+ data.tar.gz: cf273c392e0fde12e79b244819c1c880de8e11dd
5
5
  SHA512:
6
- metadata.gz: c2913f5069f689cbeedf2d8257096fb88a90755971ea45924771a1e8d3f09c1ed9af2acfd97e57a9e816bceb08b5a083245af455860f6888899d45f9f57b401d
7
- data.tar.gz: a0216507421c39e39548b138cb9277a185a0fbd1db69594975e6ecf256fc3e78e4aab7655db2eb45b11584b260354f3e24b588743eb80470accb118ca044da8b
6
+ metadata.gz: 0e20060ad75456272818d391425dad43a7deca8babe64f104a586a946221db0aa0e57d227bb16acee3ac7a3921d272a12d8da2bde3a4d2794b85a6f8233965b8
7
+ data.tar.gz: 6ab47ee0aed555756fd7ab7dadabe617985abe5c32d61efc1e4374546427abc0afebcb60185c84dfe50b87e083f8ca8ec10038120cc8480cca4adfdf7a54c8bf
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## 0.6.2
4
+
5
+ * Update dependencies (no user-facing changes).
6
+
7
+ ## 0.6.1
8
+
9
+ ### New Features
10
+
11
+ * Added #siblings scope to HasTree concern.
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2013 Rob Smith
3
+ Copyright (c) 2013-2014 Rob Smith
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
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
- **Warning:** using this option will make many write operations much, much
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
- RSpec::SleepingKingStudios is released under the
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
- module SleepingKingStudios; end
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: using this option will make many write operations much,
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
- validate_options options
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
- # Returns a Criteria specifying all root objects, e.g. objects with no
120
- # parent object.
190
+ # @!method roots
191
+ # Returns a Criteria specifying all root objects, e.g. objects with no
192
+ # parent object.
121
193
  #
122
- # @return [Mongoid::Criteria]
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
- # Returns the root object of the current object's tree.
197
+ # @!method root
198
+ # Returns the root object of the current object's tree.
149
199
  #
150
- # @return [Tree]
151
- def root
152
- parent ? parent.root : self
153
- end # method root
200
+ # @return [Tree]
154
201
 
155
- # Returns true if the object is a leaf object, e.g. has no child objects.
202
+ # @!method leaf?
203
+ # Returns true if the object is a leaf object, e.g. has no child objects.
156
204
  #
157
- # @return [Boolean] True if the object has no children; otherwise false.
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
- # Returns true if the object is a root object, e.g. has no parent object.
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
- # @return [Boolean] True if the object has no parent; otherwise false.
165
- def root?
166
- parent.nil?
167
- end # method root?
218
+ # @since 0.6.1
168
219
  end # module
169
220
  end # module