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
@@ -0,0 +1,64 @@
|
|
1
|
+
# lib/mongoid/sleeping_king_studios/has_tree/metadata.rb
|
2
|
+
|
3
|
+
require 'mongoid/sleeping_king_studios/concern/metadata'
|
4
|
+
require 'mongoid/sleeping_king_studios/has_tree/cache_ancestry/metadata'
|
5
|
+
require 'mongoid/sleeping_king_studios/has_tree/children/metadata'
|
6
|
+
require 'mongoid/sleeping_king_studios/has_tree/parent/metadata'
|
7
|
+
|
8
|
+
module Mongoid::SleepingKingStudios
|
9
|
+
module HasTree
|
10
|
+
# Stores information about a HasTree concern.
|
11
|
+
class Metadata < Mongoid::SleepingKingStudios::Concern::Metadata
|
12
|
+
# @param [Symbol, String] name The name of the concern or relation.
|
13
|
+
# @param [Hash] properties The properties of the concern or relation.
|
14
|
+
def initialize name, properties = {}
|
15
|
+
super
|
16
|
+
|
17
|
+
self[:parent] = characterize :parent, properties.fetch(:parent, {}), HasTree::Parent::Metadata
|
18
|
+
self[:children] = characterize :children, properties.fetch(:children, {}), HasTree::Children::Metadata
|
19
|
+
|
20
|
+
if properties.fetch(:cache_ancestry, false)
|
21
|
+
properties[:cache_ancestry] = {} unless Hash === properties[:cache_ancestry]
|
22
|
+
properties[:cache_ancestry][:children_name] = children.relation_name
|
23
|
+
properties[:cache_ancestry][:parent_name] = parent.relation_name
|
24
|
+
|
25
|
+
self[:cache_ancestry] = characterize :cache_ancestry, properties[:cache_ancestry], HasTree::CacheAncestry::Metadata
|
26
|
+
end # unless
|
27
|
+
end # constructor
|
28
|
+
|
29
|
+
# The metadata associated with the :cache_ancestry option.
|
30
|
+
#
|
31
|
+
# @return [Metadata] The :cache_ancestry metadata.
|
32
|
+
def cache_ancestry
|
33
|
+
self[:cache_ancestry]
|
34
|
+
end # method cache_ancestry
|
35
|
+
|
36
|
+
# @return [Boolean] True if the :cache_ancestry option is selected;
|
37
|
+
# otherwise false.
|
38
|
+
def cache_ancestry?
|
39
|
+
!!self[:cache_ancestry]
|
40
|
+
end # method cache_ancestry?
|
41
|
+
|
42
|
+
# The metadata associated with the #children relation.
|
43
|
+
#
|
44
|
+
# @return [Metadata] The children metadata.
|
45
|
+
def children
|
46
|
+
self[:children]
|
47
|
+
end # method children
|
48
|
+
|
49
|
+
# The foreign key for the parent relation.
|
50
|
+
#
|
51
|
+
# @return [Symbol] The foreign key.
|
52
|
+
def foreign_key
|
53
|
+
self[:foreign_key] || :"#{parent.relation_name}_id"
|
54
|
+
end # method foreign_key
|
55
|
+
|
56
|
+
# The metadata associated with the #parent relation.
|
57
|
+
#
|
58
|
+
# @return [Metadata] The parent metadata.
|
59
|
+
def parent
|
60
|
+
self[:parent]
|
61
|
+
end # method parent
|
62
|
+
end # class
|
63
|
+
end # module
|
64
|
+
end # module
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# lib/mongoid/sleeping_king_studios/has_tree/parent/metadata.rb
|
2
|
+
|
3
|
+
require 'mongoid/sleeping_king_studios/concern/metadata'
|
4
|
+
|
5
|
+
module Mongoid::SleepingKingStudios
|
6
|
+
module HasTree
|
7
|
+
module Parent
|
8
|
+
# Stores information about a HasTree concern's parent relation.
|
9
|
+
class Metadata < Mongoid::SleepingKingStudios::Concern::Metadata
|
10
|
+
# The name of the tree's children relation. If no relation name is set,
|
11
|
+
# defaults to :children.
|
12
|
+
#
|
13
|
+
# @return [Symbol] The relation name.
|
14
|
+
def inverse_of
|
15
|
+
fetch(:inverse_of, :children)
|
16
|
+
end # method inverse_of
|
17
|
+
|
18
|
+
# @return [Boolean] True if a custom inverse relation name is set;
|
19
|
+
# otherwise false.
|
20
|
+
def inverse_of?
|
21
|
+
!!self[:inverse_of]
|
22
|
+
end # method inverse_of?
|
23
|
+
|
24
|
+
# The name of the tree's parent relation. If no relation name is set,
|
25
|
+
# defaults to :parent.
|
26
|
+
#
|
27
|
+
# @return [Symbol] The relation name.
|
28
|
+
def relation_name
|
29
|
+
fetch(:relation_name, :parent)
|
30
|
+
end # method relation_name
|
31
|
+
|
32
|
+
# @return [Boolean] True if a custom relation name is set; otherwise
|
33
|
+
# false.
|
34
|
+
def relation_name?
|
35
|
+
!!self[:relation_name]
|
36
|
+
end # method relation_name?
|
37
|
+
end # class
|
38
|
+
end # module
|
39
|
+
end # module
|
40
|
+
end # module
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# lib/mongoid/sleeping_king_studios/sluggable.rb
|
2
2
|
|
3
|
-
require 'mongoid/sleeping_king_studios'
|
3
|
+
require 'mongoid/sleeping_king_studios/concern'
|
4
|
+
require 'mongoid/sleeping_king_studios/sluggable/metadata'
|
4
5
|
|
5
6
|
module Mongoid::SleepingKingStudios
|
6
7
|
# Adds a :slug field that stores a short, url-friendly reference string,
|
@@ -24,69 +25,147 @@ module Mongoid::SleepingKingStudios
|
|
24
25
|
# @since 0.1.0
|
25
26
|
module Sluggable
|
26
27
|
extend ActiveSupport::Concern
|
28
|
+
extend Mongoid::SleepingKingStudios::Concern
|
29
|
+
|
30
|
+
# @api private
|
31
|
+
#
|
32
|
+
# Sets up the sluggable relation, creating fields, accessors and
|
33
|
+
# validations.
|
34
|
+
#
|
35
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
36
|
+
# @param [String, Symbol] attribute The base field used to determine
|
37
|
+
# the value of the slug. When this field is changed via its writer
|
38
|
+
# method, the slug will be updated.
|
39
|
+
# @param [Hash] options The options for the relation.
|
40
|
+
#
|
41
|
+
# @since 0.6.0
|
42
|
+
def self.apply base, attribute, options
|
43
|
+
name = :sluggable
|
44
|
+
validate_options name, options
|
45
|
+
meta = characterize name, options, Metadata
|
46
|
+
meta[:attribute] = attribute
|
47
|
+
|
48
|
+
relate base, name, meta
|
49
|
+
|
50
|
+
define_fields base, meta
|
51
|
+
define_accessors base, meta
|
52
|
+
define_validations base, meta
|
53
|
+
end # module method apply
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
#
|
57
|
+
# Redefines the writer for the base attribute to overwrite the value of the
|
58
|
+
# slug field unless the slug is locked. If the Lockable option is selected,
|
59
|
+
# redefines the writer for the slug field to lock the slug when set
|
60
|
+
# manually; otherwise, makes the writer for the slug field private.
|
61
|
+
#
|
62
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
63
|
+
# @param [Metadata] metadata The metadata for the relation.
|
64
|
+
#
|
65
|
+
# @since 0.6.0
|
66
|
+
def self.define_accessors base, metadata
|
67
|
+
base.re_define_method :"#{metadata.attribute}=" do |value|
|
68
|
+
self[metadata.attribute.to_s] = value
|
69
|
+
unless metadata.lockable? && self['slug_lock']
|
70
|
+
self['slug'] = metadata.value_to_slug value
|
71
|
+
end # unless
|
72
|
+
end # method
|
73
|
+
|
74
|
+
if metadata.lockable?
|
75
|
+
base.re_define_method :slug= do |value|
|
76
|
+
self['slug'] = value
|
77
|
+
self['slug_lock'] = true
|
78
|
+
end # method
|
79
|
+
else
|
80
|
+
base.send :private, :slug=
|
81
|
+
end # if
|
82
|
+
end # module method define_accessors
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
# Creates a slug field of type String on the base class. If the Lockable
|
87
|
+
# option is selected, also creates a slug_lock field of type Boolean.
|
88
|
+
#
|
89
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
90
|
+
# @param [Metadata] metadata The metadata for the relation.
|
91
|
+
#
|
92
|
+
# @since 0.6.0
|
93
|
+
def self.define_fields base, metadata
|
94
|
+
base.send :field, :slug, :type => String
|
95
|
+
|
96
|
+
if metadata.lockable?
|
97
|
+
base.send :field, :slug_lock, :type => Boolean, :default => false
|
98
|
+
end # if
|
99
|
+
end # module method define_fields
|
100
|
+
|
101
|
+
# @api private
|
102
|
+
#
|
103
|
+
# Sets a validation on the slug field that validates the presence of the
|
104
|
+
# slug, and that the value is of a valid format (lower-case characters a-z,
|
105
|
+
# digits 0-9, and hyphens "-").
|
106
|
+
#
|
107
|
+
# @param [Class] base The base class into which the concern is mixed in.
|
108
|
+
# @param [Metadata] metadata The metadata for the relation.
|
109
|
+
#
|
110
|
+
# @since 0.6.0
|
111
|
+
def self.define_validations base, metadata
|
112
|
+
base.validates :slug,
|
113
|
+
:presence => true,
|
114
|
+
:format => {
|
115
|
+
:with => /\A[a-z0-9\-]+\z/,
|
116
|
+
:message => 'must be lower-case characters a-z, digits 0-9, and hyphens "-"'
|
117
|
+
} # end format
|
118
|
+
end # module method define_validations
|
119
|
+
|
120
|
+
# Returns a list of options that are valid for this concern.
|
121
|
+
#
|
122
|
+
# @return [Array<Symbol>] The list of valid options.
|
123
|
+
#
|
124
|
+
# @since 0.6.0
|
125
|
+
def self.valid_options
|
126
|
+
super + %i(
|
127
|
+
lockable
|
128
|
+
) # end array
|
129
|
+
end # module method valid options
|
27
130
|
|
28
131
|
# @!attribute [r] slug
|
29
132
|
# A url-friendly short string version of the specified base attribute.
|
30
|
-
#
|
133
|
+
#
|
134
|
+
# (Lockable) The slug value can be set directly using the #slug= method.
|
135
|
+
# This will set the :slug_lock flag, preventing the slug from being
|
136
|
+
# updated by a change to the base field until :slug_lock is cleared.
|
137
|
+
#
|
138
|
+
# @return [String] The value of the stored slug.
|
139
|
+
|
140
|
+
# @!attribute [rw] slug_lock
|
141
|
+
# (Lockable) A flag that indicates whether or not the slug is locked.
|
142
|
+
# If the flag is set, updating the base field will not change the value
|
143
|
+
# of the slug.
|
31
144
|
#
|
32
|
-
# @return [
|
145
|
+
# @return [Boolean] True if the slug is locked; otherwise false.
|
33
146
|
|
34
147
|
# Class methods added to the base class via #extend.
|
35
148
|
module ClassMethods
|
36
|
-
# Returns the options passed into ::slugify, as well as an additional
|
37
|
-
# :attribute value for the attribute passed into ::slugify.
|
38
|
-
attr_reader :sluggable_options
|
39
|
-
|
40
149
|
# @overload slugify attribute, options = {}
|
41
150
|
# Creates the :slug field and sets up the callback and validations.
|
42
151
|
#
|
43
|
-
# @param [String, Symbol] attribute
|
152
|
+
# @param [String, Symbol] attribute The base field used to determine
|
153
|
+
# the value of the slug. When this field is changed via its writer
|
154
|
+
# method, the slug will be updated.
|
155
|
+
# @param [Hash] options The options for the relation.
|
44
156
|
# @option options [Boolean] :lockable
|
45
157
|
# The :lockable option allows the manual setting of the :slug field.
|
46
158
|
# To do so, it adds an additional :slug_lock field, which defaults to
|
47
159
|
# false but is set to true whenever #slug= is called. If the slug is
|
48
160
|
# locked, its value is not updated to track the base attribute. To
|
49
161
|
# resume tracking the base attribute, set :slug_lock to false.
|
162
|
+
#
|
163
|
+
# @raise [Mongoid::Errors::InvalidOptions] If any of the provided
|
164
|
+
# options are invalid.
|
50
165
|
def slugify attribute, **options
|
51
|
-
|
52
|
-
|
53
|
-
field :slug, :type => String
|
54
|
-
|
55
|
-
validates :slug,
|
56
|
-
:presence => true,
|
57
|
-
:format => {
|
58
|
-
:with => /\A[a-z0-9\-]+\z/,
|
59
|
-
:message => 'must be lower-case characters a-z, digits 0-9, and hyphens "-"'
|
60
|
-
} # end format
|
61
|
-
|
62
|
-
before_validation do
|
63
|
-
return if self.class.sluggable_options[:lockable] && self.slug_lock
|
64
|
-
self[:slug] = to_slug
|
65
|
-
end # before validation callback
|
66
|
-
|
67
|
-
# Lockable
|
68
|
-
if options.fetch(:lockable, false)
|
69
|
-
field :slug_lock, :type => Boolean, :default => false
|
70
|
-
|
71
|
-
self.class_eval do
|
72
|
-
def slug= value
|
73
|
-
super
|
74
|
-
self.slug_lock = true
|
75
|
-
end # method slug=
|
76
|
-
end # class eval
|
77
|
-
else
|
78
|
-
private :slug=
|
79
|
-
end # if
|
166
|
+
concern = Mongoid::SleepingKingStudios::Sluggable
|
167
|
+
concern.apply self, attribute, options
|
80
168
|
end # class method slugify
|
81
169
|
end # module
|
82
|
-
|
83
|
-
# Processes the specified base attribute and returns a valid slug value. By
|
84
|
-
# default, calls String#parameterize.
|
85
|
-
#
|
86
|
-
# @return [String] the processed value
|
87
|
-
def to_slug
|
88
|
-
raw = (self.send self.class.sluggable_options[:attribute]) || ""
|
89
|
-
raw.parameterize
|
90
|
-
end # method to_slug
|
91
170
|
end # module
|
92
171
|
end # module
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# lib/mongoid/sleeping_king_studios/sluggable/metadata.rb
|
2
|
+
|
3
|
+
require 'mongoid/sleeping_king_studios/concern/metadata'
|
4
|
+
|
5
|
+
module Mongoid::SleepingKingStudios
|
6
|
+
module Sluggable
|
7
|
+
# Stores information about a Sluggable concern.
|
8
|
+
class Metadata < Mongoid::SleepingKingStudios::Concern::Metadata
|
9
|
+
# The base attribute used to determine the slug value.
|
10
|
+
#
|
11
|
+
# @return [Symbol] The attribute name.
|
12
|
+
def attribute
|
13
|
+
self[:attribute].to_s.intern
|
14
|
+
end # method attribute
|
15
|
+
|
16
|
+
# @return [Boolean] True if the attribute is defined; otherwise false.
|
17
|
+
def attribute?
|
18
|
+
!!self[:attribute]
|
19
|
+
end # method attribute?
|
20
|
+
|
21
|
+
# If true, the slug can be "locked" by setting the slug value directly or
|
22
|
+
# by setting the value of the :slug_lock field to true. A locked slug is
|
23
|
+
# not overwritten when the base field is updated.
|
24
|
+
#
|
25
|
+
# @return [Boolean] True if the slug is lockable; otherwise false.
|
26
|
+
def lockable?
|
27
|
+
!!self[:lockable]
|
28
|
+
end # method lockable?
|
29
|
+
|
30
|
+
# Converts the given value to a valid slug string. Refactoring this into
|
31
|
+
# the metadata will permit customization of the value -> slug mapping in
|
32
|
+
# the future.
|
33
|
+
#
|
34
|
+
# @param [Object] value The value to convert into a slug.
|
35
|
+
#
|
36
|
+
# @return [String] The converted value.
|
37
|
+
def value_to_slug value
|
38
|
+
value.to_s.parameterize
|
39
|
+
end # method value_to_slug
|
40
|
+
end # class Metadata
|
41
|
+
end # module
|
42
|
+
end # module
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-sleeping_king_studios
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob "Merlin" Smith
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.9.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sleeping_king_studios-ext
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +70,16 @@ dependencies:
|
|
56
70
|
name: rspec-sleeping_king_studios
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - ~>
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0
|
75
|
+
version: '1.0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - ~>
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0
|
82
|
+
version: '1.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: factory_girl
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,44 +112,16 @@ dependencies:
|
|
98
112
|
name: fuubar
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - '>='
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: pry
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - '>='
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - '>='
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: yard
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - '>='
|
115
|
+
- - ~>
|
130
116
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
117
|
+
version: '1.2'
|
132
118
|
type: :development
|
133
119
|
prerelease: false
|
134
120
|
version_requirements: !ruby/object:Gem::Requirement
|
135
121
|
requirements:
|
136
|
-
- -
|
122
|
+
- - ~>
|
137
123
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
124
|
+
version: '1.2'
|
139
125
|
description: |2
|
140
126
|
A collection of concerns and extensions to add functionality to Mongoid
|
141
127
|
documents and collections. The features can be included individually or by
|
@@ -146,14 +132,23 @@ executables: []
|
|
146
132
|
extensions: []
|
147
133
|
extra_rdoc_files: []
|
148
134
|
files:
|
135
|
+
- lib/mongoid/sleeping_king_studios/concern/metadata.rb
|
136
|
+
- lib/mongoid/sleeping_king_studios/concern.rb
|
149
137
|
- lib/mongoid/sleeping_king_studios/error.rb
|
138
|
+
- lib/mongoid/sleeping_king_studios/ext/mongoid/document.rb
|
139
|
+
- lib/mongoid/sleeping_king_studios/has_tree/cache_ancestry/metadata.rb
|
150
140
|
- lib/mongoid/sleeping_king_studios/has_tree/cache_ancestry.rb
|
141
|
+
- lib/mongoid/sleeping_king_studios/has_tree/children/metadata.rb
|
151
142
|
- lib/mongoid/sleeping_king_studios/has_tree/errors.rb
|
143
|
+
- lib/mongoid/sleeping_king_studios/has_tree/metadata.rb
|
144
|
+
- lib/mongoid/sleeping_king_studios/has_tree/parent/metadata.rb
|
152
145
|
- lib/mongoid/sleeping_king_studios/has_tree.rb
|
146
|
+
- lib/mongoid/sleeping_king_studios/sluggable/metadata.rb
|
153
147
|
- lib/mongoid/sleeping_king_studios/sluggable.rb
|
154
148
|
- lib/mongoid/sleeping_king_studios/version.rb
|
155
149
|
- lib/mongoid/sleeping_king_studios.rb
|
156
150
|
- LICENSE
|
151
|
+
- CHANGELOG.md
|
157
152
|
- README.md
|
158
153
|
homepage: http://sleepingkingstudios.com
|
159
154
|
licenses:
|