Skip to content

Commit ff1f680

Browse files
authoredJun 16, 2019
Merge pull request #22 from wbreeze/i20
Repair error of to_param when no slug column
2 parents f9cce2c + 697fa5c commit ff1f680

File tree

4 files changed

+70
-47
lines changed

4 files changed

+70
-47
lines changed
 

‎lib/slug/slug.rb

+50-47
Original file line numberDiff line numberDiff line change
@@ -36,63 +36,66 @@ def slug source, opts={}
3636
with: /\A[a-z0-9-]+\z/,
3737
message: "contains invalid characters. Only downcase letters, numbers, and '-' are allowed."
3838
before_validation :set_slug, :on => :create
39+
40+
include SlugInstanceMethods
3941
end
4042
end
4143

42-
# Sets the slug. Called before create.
43-
# By default, set_slug won't change slug if one already exists. Pass :force => true to overwrite.
44-
def set_slug(opts={})
45-
validate_slug_columns
46-
return if self[self.slug_column].present? && !opts[:force]
44+
module SlugInstanceMethods
45+
# Sets the slug. Called before create.
46+
# By default, set_slug won't change slug if one already exists. Pass :force => true to overwrite.
47+
def set_slug(opts={})
48+
validate_slug_columns
49+
return if self[self.slug_column].present? && !opts[:force]
4750

48-
self[self.slug_column] = normalize_slug(self.send(self.slug_source))
51+
self[self.slug_column] = normalize_slug(self.send(self.slug_source))
4952

50-
# if normalize_slug returned a blank string, try the generic_default handling
51-
if generic_default && self[self.slug_column].blank?
52-
self[self.slug_column] = self.class.to_s.demodulize.underscore.dasherize
53-
end
53+
# if normalize_slug returned a blank string, try the generic_default handling
54+
if generic_default && self[self.slug_column].blank?
55+
self[self.slug_column] = self.class.to_s.demodulize.underscore.dasherize
56+
end
5457

55-
assign_slug_sequence if self.changed_attributes.include?(self.slug_column)
56-
end
58+
assign_slug_sequence if self.changed_attributes.include?(self.slug_column)
59+
end
5760

58-
# Overwrite existing slug based on current contents of source column.
59-
def reset_slug
60-
set_slug(:force => true)
61-
end
61+
# Overwrite existing slug based on current contents of source column.
62+
def reset_slug
63+
set_slug(:force => true)
64+
end
6265

63-
# Overrides to_param to return the model's slug.
64-
def to_param
65-
self[self.slug_column]
66-
end
66+
# Overrides to_param to return the model's slug.
67+
def to_param
68+
self[self.slug_column]
69+
end
6770

68-
private
69-
# Validates that source and destination methods exist. Invoked at runtime to allow definition
70-
# of source/slug methods after <tt>slug</tt> setup in class.
71-
def validate_slug_columns
72-
raise ArgumentError, "Source column '#{self.slug_source}' does not exist!" if !self.respond_to?(self.slug_source)
73-
raise ArgumentError, "Slug column '#{self.slug_column}' does not exist!" if !self.respond_to?("#{self.slug_column}=")
74-
end
71+
private
72+
# Validates that source and destination methods exist. Invoked at runtime to allow definition
73+
# of source/slug methods after <tt>slug</tt> setup in class.
74+
def validate_slug_columns
75+
raise ArgumentError, "Source column '#{self.slug_source}' does not exist!" if !self.respond_to?(self.slug_source)
76+
raise ArgumentError, "Slug column '#{self.slug_column}' does not exist!" if !self.respond_to?("#{self.slug_column}=")
77+
end
7578

76-
# Takes the slug, downcases it and replaces non-word characters with a -.
77-
# Feel free to override this method if you'd like different slug formatting.
78-
def normalize_slug(str)
79-
return if str.blank?
80-
str.gsub!(/[\p{Pc}\p{Ps}\p{Pe}\p{Pi}\p{Pf}\p{Po}]/, '') # Remove punctuation
81-
str.parameterize
82-
end
79+
# Takes the slug, downcases it and replaces non-word characters with a -.
80+
# Feel free to override this method if you'd like different slug formatting.
81+
def normalize_slug(str)
82+
return if str.blank?
83+
str.gsub!(/[\p{Pc}\p{Ps}\p{Pe}\p{Pi}\p{Pf}\p{Po}]/, '') # Remove punctuation
84+
str.parameterize
85+
end
8386

84-
# If a slug of the same name already exists, this will append '-n' to the end of the slug to
85-
# make it unique. The second instance gets a '-1' suffix.
86-
def assign_slug_sequence
87-
return if self[self.slug_column].blank?
88-
assoc = self.class.base_class
89-
base_slug = self[self.slug_column]
90-
seq = 0
91-
92-
while assoc.where(self.slug_column => self[self.slug_column]).exists? do
93-
seq += 1
94-
self[self.slug_column] = "#{base_slug}-#{seq}"
87+
# If a slug of the same name already exists, this will append '-n' to the end of the slug to
88+
# make it unique. The second instance gets a '-1' suffix.
89+
def assign_slug_sequence
90+
return if self[self.slug_column].blank?
91+
assoc = self.class.base_class
92+
base_slug = self[self.slug_column]
93+
seq = 0
94+
95+
while assoc.where(self.slug_column => self[self.slug_column]).exists? do
96+
seq += 1
97+
self[self.slug_column] = "#{base_slug}-#{seq}"
98+
end
9599
end
96100
end
97-
98-
end
101+
end

‎test/models.rb

+3
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ class Generation < ActiveRecord::Base
3434
slug :title, generic_default: true
3535
end
3636

37+
# Test model with no slug column
38+
class Orphan < ActiveRecord::Base
39+
end

‎test/schema.rb

+6
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,10 @@
3232
t.column "title", "string"
3333
t.column "slug", "string", null: false
3434
end
35+
36+
# table with no slug column
37+
create_table "orphans", :force => true do |t|
38+
t.column "name", "string"
39+
t.column "location", "string"
40+
end
3541
end

‎test/slug_test.rb

+11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@
1717
assert_equal 'test-event-portland', article.slug
1818
end
1919

20+
it "bases to_param on slug" do
21+
article = Article.create!(:headline => 'Test Headline')
22+
assert_equal(article.slug, article.to_param)
23+
end
24+
25+
it "does not impact lookup of model with no slug column" do
26+
orphan = Orphan.create!(:name => 'Oliver')
27+
query = orphan.to_param
28+
assert_equal(orphan.id.to_s, query)
29+
end
30+
2031
describe "slug column" do
2132
it "saves slug to 'slug' column by default" do
2233
article = Article.create!(:headline => 'Test Headline')

0 commit comments

Comments
 (0)
Please sign in to comment.