Module: Mongoid::SleepingKingStudios::Sluggable

Extended by:
ActiveSupport::Concern, Concern
Defined in:
lib/mongoid/sleeping_king_studios/sluggable.rb,
lib/mongoid/sleeping_king_studios/sluggable/metadata.rb

Overview

Adds a :slug field that stores a short, url-friendly reference string, useful for human-readable urls. By default, the slug field is automatically overwritten from the specified base attribute before validation. To enable setting the slug manually, use the :lockable option; otherwise, the :slug= writer is set to private.

Examples:

Setting up the slug:

class SluggableDocument
  include Mongoid::Document
  include Mongoid::SleepingKingStudios::Sluggable

  field :title, :type => String

  slugify :title
end # class

See Also:

Since:

  • 0.1.0

Defined Under Namespace

Modules: ClassMethods Classes: Metadata

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Concern

characterize, relate, valid_options, validate_options

Instance Attribute Details

#slugString (readonly)

A url-friendly short string version of the specified base attribute.

(Lockable) The slug value can be set directly using the #slug= method. This will set the :slug_lock flag, preventing the slug from being updated by a change to the base field until :slug_lock is cleared.

Returns:

  • (String)

    The value of the stored slug.



# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 174

#slug_lockBoolean

(Lockable) A flag that indicates whether or not the slug is locked. If the flag is set, updating the base field will not change the value of the slug.

Returns:

  • (Boolean)

    True if the slug is locked; otherwise false.



# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 183

Class Method Details

.apply(base, attribute, options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Sets up the sluggable relation, creating fields, accessors and validations.

Parameters:

  • base (Class)

    The base class into which the concern is mixed in.

  • attribute (String, Symbol)

    The base field used to determine the value of the slug. When this field is changed via its writer method, the slug will be updated.

  • options (Hash)

    The options for the relation.

Since:

  • 0.6.0



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 42

def self.apply base, attribute, options
  name = :sluggable
  validate_options    name, options
  meta = characterize name, options, Metadata
  meta[:attribute] = attribute

  relate base, name, meta

  define_fields      base, meta
  define_accessors   base, meta
  define_helpers     base, meta
  define_validations base, meta
end

.define_accessors(base, metadata) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Redefines the writer for the base attribute to overwrite the value of the slug field unless the slug is locked. If the Lockable option is selected, redefines the writer for the slug field to lock the slug when set manually; otherwise, makes the writer for the slug field private.

Parameters:

  • base (Class)

    The base class into which the concern is mixed in.

  • metadata (Metadata)

    The metadata for the relation.

Since:

  • 0.6.0



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 67

def self.define_accessors base, 
  base.re_define_method :"#{.attribute}=" do |value|
    self[.attribute.to_s] = value
    unless .lockable? && self['slug_lock']
      self['slug'] = .value_to_slug value
    end # unless
  end # method

  if .lockable?
    base.re_define_method :slug= do |value|
      self['slug'] = value
      self['slug_lock'] = true
    end # method
  else
    base.send :private, :slug=
  end # if
end

.define_fields(base, metadata) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a slug field of type String on the base class. If the Lockable option is selected, also creates a slug_lock field of type Boolean.

Parameters:

  • base (Class)

    The base class into which the concern is mixed in.

  • metadata (Metadata)

    The metadata for the relation.

Since:

  • 0.6.0



94
95
96
97
98
99
100
# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 94

def self.define_fields base, 
  base.send :field, :slug, :type => String

  if .lockable?
    base.send :field, :slug_lock, :type => Boolean, :default => false
  end # if
end

.define_helpers(base, metadata) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates the ::slugify_all! class-level helper method.

Parameters:

  • base (Class)

    The base class into which the concern is mixed in.

  • metadata (Metadata)

    The metadata for the relation.

Since:

  • 0.7.7



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 110

def self.define_helpers base, 
  instance_methods = Module.new

  instance_methods.send :define_method, :generate_slug! do
    value = .value_to_slug(send .attribute)
    if slug.blank?
      self[:slug] = value
      self.set :slug => value if persisted?
    elsif slug != value && !(.lockable? && slug_lock)
      self[:slug] = value
      self.set :slug => value if persisted?
    end # if
  end # method generate_slug!

  instance_methods.send :define_method, :to_slug do
    .value_to_slug(send .attribute)
  end # method to_slug

  base.include instance_methods

  # Define class-level helpers.
  class_methods = Module.new

  class_methods.send :define_method, :slugify_all! do
    all.map &:generate_slug!
  end # class method slugify_all!

  class_methods.send :define_method, :value_to_slug do |value|
    .value_to_slug(value)
  end # class method value_to_slug

  base.extend class_methods
end

.define_validations(base, metadata) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Sets a validation on the slug field that validates the presence of the slug, and that the value is of a valid format (lower-case characters a-z, digits 0-9, and hyphens “-”).

Parameters:

  • base (Class)

    The base class into which the concern is mixed in.

  • metadata (Metadata)

    The metadata for the relation.

Since:

  • 0.6.0



154
155
156
157
158
159
160
161
# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 154

def self.define_validations base, 
  base.validates :slug,
    :presence => true,
    :format => {
      :with => /\A[a-z0-9\-]+\z/,
      :message => 'must be lower-case characters a-z, digits 0-9, and hyphens "-"'
    } # end format
end

.valid_optionsArray<Symbol>

Returns a list of options that are valid for this concern.

Returns:

  • (Array<Symbol>)

    The list of valid options.

Since:

  • 0.6.0



168
169
170
171
172
# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 168

def self.valid_options
  super + %i(
    lockable
  ) # end array
end

Instance Method Details

#generate_slug!Object

If the document’s slug is blank, or if it does not match the base attribute value, calculates the value from the base attribute and assigns it atomically. Locked slugs (see the :lockable option) are unaffected.

Since:

  • 0.7.8



# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 190

#to_slugString

Converts the current value of the base attribute to a slug value, but returns the converted value instead of changing the slug field.

Returns:

  • (String)

    The converted string.

Since:

  • 0.7.8



# File 'lib/mongoid/sleeping_king_studios/sluggable.rb', line 198