Sha256: a8ef0b0b3511a7f94fcbe30075aca3b3fa7082335f0c858d5a347185db97332e

Contents?: true

Size: 1.95 KB

Versions: 4

Compression:

Stored size: 1.95 KB

Contents

module FriendlyId
  # This class offers functionality to check slug strings for uniqueness and,
  # if necessary, append a sequence to ensure it.
  class SlugSequencer
    attr_reader :sluggable

    def initialize(sluggable)
      @sluggable = sluggable
    end

    # Given a slug, get the next available slug in the sequence.
    def next
      sequence = conflict.slug.split(separator)[1].to_i
      next_sequence = sequence == 0 ? 2 : sequence.next
      "#{normalized}#{separator}#{next_sequence}"
    end

    # Generate a new sequenced slug.
    def generate
      if new_record? or slug_changed?
        conflict? ? self.next : normalized
      else
        sluggable.friendly_id
      end
    end

    # Whether or not the model instance's slug has changed.
    def slug_changed?
      separator = Regexp.escape friendly_id_config.sequence_separator
      base != sluggable.current_friendly_id.try(:sub, /#{separator}[\d]*\z/, '')
    end

    private

    def base
      sluggable.send friendly_id_config.base
    end

    def column
      sluggable.connection.quote_column_name friendly_id_config.query_field
    end

    def conflict?
      !! conflict
    end

    def conflict
      unless defined? @conflict
        @conflict = conflicts.first
      end
      @conflict
    end

    def conflicts
      pkey  = sluggable.class.primary_key
      value = sluggable.send pkey
      scope = sluggable.class.where("#{column} = ? OR #{column} LIKE ?", normalized, wildcard)
      scope = scope.where("#{pkey} <> ?", value) unless sluggable.new_record?
      scope = scope.order("LENGTH(#{column}) DESC, #{column} DESC")
    end

    def friendly_id_config
      sluggable.friendly_id_config
    end

    def new_record?
      sluggable.new_record?
    end

    def normalized
      @normalized ||= sluggable.normalize_friendly_id(base)
    end

    def separator
      friendly_id_config.sequence_separator
    end

    def wildcard
      "#{normalized}#{separator}%"
    end
  end
end

Version data entries

4 entries across 4 versions & 2 rubygems

Version Path
friendly_id-4.0.0.beta8 lib/friendly_id/slug_sequencer.rb
friendly_id-4.0.0.beta7 lib/friendly_id/slug_sequencer.rb
friendly_id4-4.0.0.beta6 lib/friendly_id/slug_sequencer.rb
friendly_id4-4.0.0.beta5 lib/friendly_id/slug_sequencer.rb