Sha256: 8fe2508200a5e40a164bbcdbc03c4b51ebd6274bee0fc73fd4368100aee11c00

Contents?: true

Size: 1.67 KB

Versions: 64

Compression:

Stored size: 1.67 KB

Contents

# ActsAsSlugged
#
# This module automatically generates slugs based on the :to_s field using a before_validation filter
#
# Mark your model with 'acts_as_slugged' make sure you have a string field :slug

module ActsAsSlugged
  extend ActiveSupport::Concern

  module Base
    def acts_as_slugged(options = nil)
      include ::ActsAsSlugged
    end
  end

  included do
    extend FinderMethods

    before_validation do
      assign_attributes(slug: build_slug) if slug.blank?
    end

    validates :slug,
      presence: true, uniqueness: true, exclusion: { in: excluded_slugs }, length: { maximum: 255 },
      format: { with: /\A[a-zA-Z0-9_-]*\z/, message: 'only _ and - symbols allowed. no spaces either.' }
  end

  module ClassMethods
    def relation
      super.tap { |relation| relation.extend(FinderMethods) }
    end

    def excluded_slugs
      ::ActiveRecord::Base.connection.tables.map { |x| x }.compact
    end
  end

  module FinderMethods
    def find(*args)
      return super unless args.length == 1
      return super if block_given?

      where(slug: args.first).or(where(id: args.first)).first || raise(::ActiveRecord::RecordNotFound.new("Couldn't find #{name} with 'slug'=#{args.first}"))
    end

    def find_by_slug_or_id(*args)
      where(slug: args.first).or(where(id: args.first)).first
    end

  end

  # Instance Methods
  def build_slug
    slug = to_s.parameterize.downcase[0, 250]

    if self.class.excluded_slugs.include?(slug)
      slug = "#{slug}-#{self.class.name.demodulize.parameterize}"
    end

    if (count = self.class.where(slug: slug).count) > 0
      slug = "#{slug}-#{count+1}"
    end

    slug
  end

  def to_param
    slug_was || slug
  end

end

Version data entries

64 entries across 64 versions & 1 rubygems

Version Path
effective_resources-2.1.2 app/models/concerns/acts_as_slugged.rb
effective_resources-2.1.1 app/models/concerns/acts_as_slugged.rb
effective_resources-2.1.0 app/models/concerns/acts_as_slugged.rb
effective_resources-2.0.4 app/models/concerns/acts_as_slugged.rb
effective_resources-2.0.3 app/models/concerns/acts_as_slugged.rb
effective_resources-2.0.2 app/models/concerns/acts_as_slugged.rb
effective_resources-2.0.1 app/models/concerns/acts_as_slugged.rb
effective_resources-2.0.0 app/models/concerns/acts_as_slugged.rb
effective_resources-1.19.1 app/models/concerns/acts_as_slugged.rb
effective_resources-1.19.0 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.10 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.9 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.8 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.7 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.6 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.5 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.4 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.3 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.2 app/models/concerns/acts_as_slugged.rb
effective_resources-1.18.1 app/models/concerns/acts_as_slugged.rb