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