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.
@@ -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
- # Read-only unless the :lockable option is selected.
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 [String] the slug value
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
- @sluggable_options = options.merge :attribute => attribute.to_s.intern
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
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Mongoid
4
4
  module SleepingKingStudios
5
- VERSION = '0.5.0'
5
+ # The current version of the gem.
6
+ VERSION = '0.6.2'
6
7
  end # module
7
8
  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.5.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.0.rc.3
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.0.rc.3
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: '0'
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: '0'
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: