Class: FriendlyId::SequentiallySlugged::Calculator
- Inherits:
-
Object
- Object
- FriendlyId::SequentiallySlugged::Calculator
- Defined in:
- lib/friendly_id/sequentially_slugged/calculator.rb
Instance Attribute Summary collapse
-
#scope ⇒ Object
Returns the value of attribute scope.
-
#sequence_separator ⇒ Object
Returns the value of attribute sequence_separator.
-
#slug ⇒ Object
Returns the value of attribute slug.
-
#slug_column ⇒ Object
Returns the value of attribute slug_column.
Instance Method Summary collapse
- #conflict_query ⇒ Object private
-
#initialize(scope, slug, slug_column, sequence_separator, base_class) ⇒ Calculator
constructor
A new instance of Calculator.
- #last_sequence_number ⇒ Object private
- #next_sequence_number ⇒ Object private
- #next_slug ⇒ Object
-
#ordering_query ⇒ Object
private
Return the unnumbered (shortest) slug first, followed by the numbered ones in ascending order.
- #regexp ⇒ Object private
- #sequential_slug_matcher ⇒ Object private
- #slug_conflicts ⇒ Object private
- #sql_length ⇒ Object private
Constructor Details
#initialize(scope, slug, slug_column, sequence_separator, base_class) ⇒ Calculator
Returns a new instance of Calculator.
6 7 8 9 10 11 12 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 6 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 |
Instance Attribute Details
#scope ⇒ Object
Returns the value of attribute scope.
4 5 6 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 4 def scope @scope end |
#sequence_separator ⇒ Object
Returns the value of attribute sequence_separator.
4 5 6 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 4 def sequence_separator @sequence_separator end |
#slug ⇒ Object
Returns the value of attribute slug.
4 5 6 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 4 def slug @slug end |
#slug_column ⇒ Object
Returns the value of attribute slug_column.
4 5 6 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 4 def slug_column @slug_column end |
Instance Method Details
#conflict_query ⇒ Object (private)
20 21 22 23 24 25 26 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 20 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 /sqlite/i.match?(scope.connection.adapter_name) base end |
#last_sequence_number ⇒ Object (private)
32 33 34 35 36 37 38 39 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 32 def last_sequence_number # 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 { |slug_conflict| regexp.match(slug_conflict)[1].to_i } .max end |
#next_sequence_number ⇒ Object (private)
28 29 30 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 28 def next_sequence_number last_sequence_number ? last_sequence_number + 1 : 2 end |
#next_slug ⇒ Object
14 15 16 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 14 def next_slug slug + sequence_separator + next_sequence_number.to_s end |
#ordering_query ⇒ Object (private)
Return the unnumbered (shortest) slug first, followed by the numbered ones in ascending order.
43 44 45 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 43 def ordering_query "#{sql_length}(#{slug_column}) ASC, #{slug_column} ASC" end |
#regexp ⇒ Object (private)
47 48 49 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 47 def regexp /#{slug}#{sequence_separator}(\d+)\z/ end |
#sequential_slug_matcher ⇒ Object (private)
51 52 53 54 55 56 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 51 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 ⇒ Object (private)
58 59 60 61 62 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 58 def slug_conflicts scope .where(conflict_query, slug, sequential_slug_matcher) .order(Arel.sql(ordering_query)).pluck(Arel.sql(slug_column)) end |
#sql_length ⇒ Object (private)
64 65 66 |
# File 'lib/friendly_id/sequentially_slugged/calculator.rb', line 64 def sql_length /sqlserver/i.match?(scope.connection.adapter_name) ? "LEN" : "LENGTH" end |