module Mongoid::SleepingKingStudios::Sluggable
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.
@example Setting up the slug:
class SluggableDocument include Mongoid::Document include Mongoid::SleepingKingStudios::Sluggable field :title, :type => String slugify :title end # class
@see ClassMethods#slugify
@since 0.1.0
Public Class Methods
@api private
Sets up the sluggable relation, creating fields, accessors and validations.
@param [Class] base The base class into which the concern is mixed in. @param [String, Symbol] attribute 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.
@param [Hash] options The options for the relation.
@since 0.6.0
# 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
@api private
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.
@param [Class] base The base class into which the concern is mixed in. @param [Metadata] metadata The metadata for the relation.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/sluggable.rb, line 67 def self.define_accessors base, metadata base.re_define_method :"#{metadata.attribute}=" do |value| self[metadata.attribute.to_s] = value unless metadata.lockable? && self['slug_lock'] self['slug'] = metadata.value_to_slug value end # unless end # method if metadata.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
@api private
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.
@param [Class] base The base class into which the concern is mixed in. @param [Metadata] metadata The metadata for the relation.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/sluggable.rb, line 94 def self.define_fields base, metadata base.send :field, :slug, :type => String if metadata.lockable? base.send :field, :slug_lock, :type => Boolean, :default => false end # if end
@api private
Creates the ::slugify_all! class-level helper method.
@param [Class] base The base class into which the concern is mixed in. @param [Metadata] metadata The metadata for the relation.
@since 0.7.7
# File lib/mongoid/sleeping_king_studios/sluggable.rb, line 110 def self.define_helpers base, metadata instance_methods = Module.new instance_methods.send :define_method, :generate_slug! do value = metadata.value_to_slug(send metadata.attribute) if slug.blank? self[:slug] = value self.set :slug => value if persisted? elsif slug != value && !(metadata.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 metadata.value_to_slug(send metadata.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| metadata.value_to_slug(value) end # class method value_to_slug base.extend class_methods end
@api private
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 “-”).
@param [Class] base The base class into which the concern is mixed in. @param [Metadata] metadata The metadata for the relation.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/sluggable.rb, line 154 def self.define_validations base, metadata 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
Returns a list of options that are valid for this concern.
@return [Array<Symbol>] The list of valid options.
@since 0.6.0
# File lib/mongoid/sleeping_king_studios/sluggable.rb, line 168 def self.valid_options super + %i( lockable ) # end array end