class FriendlyId::SequentiallySlugged::SequentialSlugCalculator
Attributes
scope[RW]
sequence_separator[RW]
slug[RW]
slug_column[RW]
Public Class Methods
new(scope, slug, slug_column, sequence_separator, base_class)
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 20 def initialize(scope, slug, slug_column, sequence_separator, base_class) @scope = scope @slug = slug table_name = scope.connection.quote_table_name(base_class.arel_table.name) @slug_column = "#{table_name}.#{scope.connection.quote_column_name(slug_column)}" @sequence_separator = sequence_separator end
Public Instance Methods
next_slug()
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 28 def next_slug slug + sequence_separator + next_sequence_number.to_s end
Private Instance Methods
conflict_query()
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 53 def conflict_query base = "#{slug_column} = ? OR #{slug_column} LIKE ?" # Awful hack for SQLite3, which does not pick up '\' as the escape character # without this. base << " ESCAPE '\\'" if scope.connection.adapter_name =~ /sqlite/i base end
last_sequence_number()
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 38 def last_sequence_number regexp = /#{slug}#{sequence_separator}(\d+)\z/ # Reject slug_conflicts that doesn't come from the first_candidate # Map all sequence numbers and take the maximum slug_conflicts.reject{ |slug_conflict| !regexp.match(slug_conflict) }.map do |slug_conflict| regexp.match(slug_conflict)[1].to_i end.max end
next_sequence_number()
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 34 def next_sequence_number last_sequence_number ? last_sequence_number + 1 : 2 end
ordering_query()
click to toggle source
Return the unnumbered (shortest) slug first, followed by the numbered ones in ascending order.
# File lib/friendly_id/sequentially_slugged.rb, line 70 def ordering_query length_command = "LENGTH" length_command = "LEN" if scope.connection.adapter_name =~ /sqlserver/i "#{length_command}(#{slug_column}) ASC, #{slug_column} ASC" end
sequential_slug_matcher()
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 61 def sequential_slug_matcher # Underscores (matching a single character) and percent signs (matching # any number of characters) need to be escaped. While this looks like # an excessive number of backslashes, it is correct. "#{slug}#{sequence_separator}".gsub(/[_%]/, '\\\&') + '%' end
slug_conflicts()
click to toggle source
# File lib/friendly_id/sequentially_slugged.rb, line 47 def slug_conflicts scope. where(conflict_query, slug, sequential_slug_matcher). order(Arel.sql(ordering_query)).pluck(Arel.sql(slug_column)) end