slug 4.1.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/lib/slug/slug.rb +50 -47
- data/slug.gemspec +1 -1
- data/test/models.rb +3 -0
- data/test/schema.rb +6 -0
- data/test/slug_test.rb +11 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65d6b738a1e306b5803f1b92e8328ed20632eb0d7706eb2417a198bd1acf8bfc
|
4
|
+
data.tar.gz: b1833f858513babd75d2f94ef776831fab3cc2e105ed9df33bf2912c9d7feb5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b46a5b3226a1b4adbdf027fe9c7692d2a33431a5aa0b67ef99edd6297974008789407eee80cd614b8d65a5bfdcbadd6c2112c554e7d79e7198571ccee967a52
|
7
|
+
data.tar.gz: d9e07b0b4b55810ab4eaff7f828755bf0bdf0d5e6744cc8ba866e50e96642db707ee459d0c8b31288ef9978cf82677a386163a646e7eff570662587395996b02
|
data/README.md
CHANGED
@@ -110,6 +110,10 @@ slug and move on.
|
|
110
110
|
* If a slug already exists, Slug will automatically append a '-n' suffix to your slug to make it unique. The second instance of a slug is '-1'.
|
111
111
|
* If you don't like the slug formatting or the accented character stripping doesn't work for you, it's easy to override Slug's formatting functions. Check the source for details.
|
112
112
|
|
113
|
+
## Development
|
114
|
+
|
115
|
+
`rake test` will run the included unit tests.
|
116
|
+
|
113
117
|
## Authors
|
114
118
|
|
115
119
|
Ben Koski, ben.koski@gmail.com
|
data/lib/slug/slug.rb
CHANGED
@@ -36,63 +36,66 @@ module Slug
|
|
36
36
|
with: /\A[a-z0-9-]+\z/,
|
37
37
|
message: "contains invalid characters. Only downcase letters, numbers, and '-' are allowed."
|
38
38
|
before_validation :set_slug, :on => :create
|
39
|
+
|
40
|
+
include SlugInstanceMethods
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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]
|
47
50
|
|
48
|
-
|
51
|
+
self[self.slug_column] = normalize_slug(self.send(self.slug_source))
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
assign_slug_sequence if self.changed_attributes.include?(self.slug_column)
|
59
|
+
end
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
# Overwrite existing slug based on current contents of source column.
|
62
|
+
def reset_slug
|
63
|
+
set_slug(:force => true)
|
64
|
+
end
|
62
65
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
66
|
+
# Overrides to_param to return the model's slug.
|
67
|
+
def to_param
|
68
|
+
self[self.slug_column]
|
69
|
+
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
75
78
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
83
86
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
95
99
|
end
|
96
100
|
end
|
97
|
-
|
98
|
-
end
|
101
|
+
end
|
data/slug.gemspec
CHANGED
data/test/models.rb
CHANGED
data/test/schema.rb
CHANGED
@@ -32,4 +32,10 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
32
32
|
t.column "title", "string"
|
33
33
|
t.column "slug", "string", null: false
|
34
34
|
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
|
35
41
|
end
|
data/test/slug_test.rb
CHANGED
@@ -17,6 +17,17 @@ describe Slug do
|
|
17
17
|
assert_equal 'test-event-portland', article.slug
|
18
18
|
end
|
19
19
|
|
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
|
+
|
20
31
|
describe "slug column" do
|
21
32
|
it "saves slug to 'slug' column by default" do
|
22
33
|
article = Article.create!(:headline => 'Test Headline')
|