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 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