From 9a10063959052c1eee118044c20ed23c98b7e449 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Fri, 7 Apr 2017 15:04:36 +0300 Subject: [PATCH 1/2] Allow to set slug limit --- lib/friendly_id/slugged.rb | 24 +++++++++++++++++++----- test/slugged_test.rb | 27 ++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/lib/friendly_id/slugged.rb b/lib/friendly_id/slugged.rb index 9891ca2ca..e8f901e94 100644 --- a/lib/friendly_id/slugged.rb +++ b/lib/friendly_id/slugged.rb @@ -288,7 +288,9 @@ def self.included(model_class) # @param [#to_s] value The value used as the basis of the slug. # @return The candidate slug text, without a sequence. def normalize_friendly_id(value) - value.to_s.parameterize + value = value.to_s.parameterize + value = value[0...friendly_id_config.slug_limit] if friendly_id_config.slug_limit + value end # Whether to generate a new slug. @@ -300,7 +302,14 @@ def should_generate_new_friendly_id? end def resolve_friendly_id_conflict(candidates) - [candidates.first, SecureRandom.uuid].compact.join(friendly_id_config.sequence_separator) + candidate = candidates.first + uid = SecureRandom.uuid + if candidate && friendly_id_config.slug_limit + max_candidate_size = friendly_id_config.slug_limit - uid.size - friendly_id_config.sequence_separator.size + max_candidate_size = [max_candidate_size, 0].max + candidate = candidate[0...max_candidate_size] + end + [candidate, uid].compact.join(friendly_id_config.sequence_separator) end # Sets the slug. @@ -334,11 +343,11 @@ def unset_slug_if_invalid end private :unset_slug_if_invalid - # This module adds the `:slug_column`, and `:sequence_separator`, and - # `:slug_generator_class` configuration options to + # This module adds the `:slug_column`, and `:slug_limit`, and `:sequence_separator`, + # and `:slug_generator_class` configuration options to # {FriendlyId::Configuration FriendlyId::Configuration}. module Configuration - attr_writer :slug_column, :sequence_separator + attr_writer :slug_column, :slug_limit, :sequence_separator attr_accessor :slug_generator_class # Makes FriendlyId use the slug column for querying. @@ -361,6 +370,11 @@ def sequence_separator def slug_column @slug_column ||= defaults[:slug_column] end + + # The limit that will be used for slug. + def slug_limit + @slug_limit ||= defaults[:slug_limit] + end end end end diff --git a/test/slugged_test.rb b/test/slugged_test.rb index 7e77cfcee..4a4943d14 100644 --- a/test/slugged_test.rb +++ b/test/slugged_test.rb @@ -271,6 +271,31 @@ def self.name end +class SlugLimitTest < TestCaseClass + + include FriendlyId::Test + + class Journalist < ActiveRecord::Base + extend FriendlyId + friendly_id :name, :use => :slugged, :slug_limit => 40 + end + + def model_class + Journalist + end + + test "should limit slug size" do + transaction do + m1 = model_class.create! :name => 'a' * 50 + assert_equal m1.slug, 'a' * 40 + m2 = model_class.create! :name => m1.name + m2.save! + # "aaa-" + assert_match(/\Aa{3}\-/, m2.slug) + end + end +end + class DefaultScopeTest < TestCaseClass include FriendlyId::Test @@ -424,4 +449,4 @@ class Novel < ActiveRecord::Base assert_equal novel.id.to_s, novel.to_param end end -end \ No newline at end of file +end From 9895a74d7202ffa966d9c163afa0b43727cf587b Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Fri, 7 Apr 2017 15:22:51 +0300 Subject: [PATCH 2/2] Added docs for `slug_limit` option --- lib/friendly_id/base.rb | 3 +++ lib/friendly_id/initializer.rb | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/lib/friendly_id/base.rb b/lib/friendly_id/base.rb index 224bf666c..2844d1498 100644 --- a/lib/friendly_id/base.rb +++ b/lib/friendly_id/base.rb @@ -178,6 +178,9 @@ module Base # Configures the name of the column where FriendlyId will store the slug. # Defaults to `:slug`. # + # @option options [Integer] :slug_limit Available when using `:slugged`. + # Configures the limit of the slug. This option has no default value. + # # @option options [Symbol] :slug_generator_class Available when using `:slugged`. # Sets the class used to generate unique slugs. You should not specify this # unless you're doing some extensive hacking on FriendlyId. Defaults to diff --git a/lib/friendly_id/initializer.rb b/lib/friendly_id/initializer.rb index b372367f4..1d8107c9a 100644 --- a/lib/friendly_id/initializer.rb +++ b/lib/friendly_id/initializer.rb @@ -52,6 +52,10 @@ # # config.slug_column = 'slug' # + # By default, slug has no size limit, but you can change it if you wish. + # + # config.slug_limit = 255 + # # When FriendlyId can not generate a unique ID from your base method, it appends # a UUID, separated by a single dash. You can configure the character used as the # separator. If you're upgrading from FriendlyId 4, you may wish to replace this