Sha256: 8b2879509562e5c45a616be349f1abe6af8a0a3d273f451a8b5cbe922806710a

Contents?: true

Size: 1.25 KB

Versions: 3

Compression:

Stored size: 1.25 KB

Contents

# frozen_string_literal: true

require "active_support/concern"

module Decidim
  # This concern contains the logic related to nicknames.
  module Nicknamizable
    extend ActiveSupport::Concern

    included do
      validates :nickname, length: { maximum: nickname_max_length }, allow_blank: true
    end

    class_methods do
      #
      # Maximum allowed nickname length
      #
      def nickname_max_length
        20
      end

      #
      # Converts any string into a valid nickname
      #
      # * Parameterizes it so it's valid as a URL.
      # * Trims length so it fits validation constraints.
      # * Disambiguates it so it's unique.
      #
      def nicknamize(name)
        disambiguate(name.parameterize(separator: "_")[nickname_length_range])
      end

      private

      def nickname_length_range
        (0...nickname_max_length)
      end

      def disambiguate(name)
        candidate = name

        2.step do |n|
          return candidate unless exists?(nickname: candidate)

          candidate = numbered_variation_of(candidate, n)
        end
      end

      def numbered_variation_of(name, number)
        appendix = "_#{number}"

        "#{name[0...(nickname_max_length - appendix.length)]}#{appendix}"
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
decidim-core-0.9.2 lib/decidim/nicknamizable.rb
decidim-core-0.9.1 lib/decidim/nicknamizable.rb
decidim-core-0.9.0 lib/decidim/nicknamizable.rb