has_unique_slug 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/README.md +18 -10
- data/lib/has_unique_slug/version.rb +1 -1
- data/lib/has_unique_slug.rb +24 -15
- data/spec/has_unique_slug_spec.rb +5 -0
- data/spec/spec_helper.rb +8 -0
- metadata +9 -6
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,7 @@ Add `gem has_unique_slug` to your Gemfile and run `bundle install` to get it ins
|
|
7
7
|
|
8
8
|
## Usage
|
9
9
|
|
10
|
-
Assume you have a Post model that has a title and slug column
|
10
|
+
Assume you have a Post model that has a title and slug column, you can use the following to uniquely parameterize title:
|
11
11
|
|
12
12
|
class Post < ActiveRecord::Base
|
13
13
|
has_unique_slug
|
@@ -15,23 +15,31 @@ Assume you have a Post model that has a title and slug column in which the slug
|
|
15
15
|
|
16
16
|
|
17
17
|
A unique slug will be generated automatically on creation.
|
18
|
-
If the generated slug is not unique,
|
19
|
-
|
18
|
+
If the generated slug is not unique, a number is added onto the end to endure uniqueness. The series starts at 2 and increments
|
19
|
+
up by one until a unique slug is found.
|
20
|
+
If a slug is already specified, this slug will be used however the above rules still apply for uniqueness.
|
20
21
|
|
21
22
|
You can specify which column to use to generate the slug and which column to use to store the slug. Below is the default:
|
22
23
|
|
23
24
|
class Post < ActiveRecord::Base
|
24
|
-
has_unique_slug :
|
25
|
-
end
|
26
|
-
|
25
|
+
has_unique_slug :slug, :title
|
26
|
+
end
|
27
27
|
|
28
|
-
Or if only 1 argument is given, use that column to
|
28
|
+
Or if only 1 argument is given, use that column to store the slug:
|
29
29
|
|
30
30
|
class Post < ActiveRecord::Base
|
31
|
-
has_unique_slug :
|
31
|
+
has_unique_slug :permalink # Uses the permalink column to store the slug
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
|
+
Optionally, a block can be provided to generate the slug:
|
35
|
+
|
36
|
+
class Car < ActiveRecord::Base
|
37
|
+
has_unique_slug {|car| "#{car.year} #{car.name}"}
|
38
|
+
end
|
39
|
+
Note the space: parameterize will be called on the result of the block to ensure the slug is url friendly.
|
34
40
|
|
35
41
|
## TODO:
|
36
42
|
|
37
|
-
Would like to write some tests.
|
43
|
+
- Would like to write some tests.
|
44
|
+
- Would like to be able to specify scope for uniqueness
|
45
|
+
- Possibly consider optimizing the method to ensure uniqueness
|
data/lib/has_unique_slug.rb
CHANGED
@@ -5,24 +5,37 @@ module HasUniqueSlug
|
|
5
5
|
base.extend ClassMethods
|
6
6
|
end
|
7
7
|
|
8
|
+
# Builds a slug from the subject_column unless a block is specified.
|
9
|
+
# If a block is specified, the result of the block is returned.
|
10
|
+
def build_slug(record, subject_column, &block)
|
11
|
+
( block_given? ? yield(record) : record[subject_column] ).parameterize
|
12
|
+
end
|
13
|
+
|
8
14
|
module ClassMethods
|
9
15
|
|
10
|
-
def has_unique_slug(
|
16
|
+
def has_unique_slug(*args, &block)
|
17
|
+
|
18
|
+
options = { :scope => nil }
|
19
|
+
options.merge! args.pop if args.last.is_a? Hash
|
20
|
+
slug_column, subject_column = args
|
21
|
+
slug_column ||= :slug
|
22
|
+
subject_column ||= :title
|
11
23
|
|
12
24
|
# Add ActiveRecord Callback
|
13
|
-
|
25
|
+
before_save do |record|
|
14
26
|
|
15
27
|
# Add a slug if slug doesn't exist
|
16
|
-
|
17
|
-
record[slug_col] = record[title_col].parameterize
|
18
|
-
end
|
28
|
+
slug_prefix = record[slug_column].blank? ? build_slug(record, subject_column, &block) : record[slug_column]
|
19
29
|
|
20
30
|
# Ensure the current slug is unique in the database, if not, make it unqiue
|
21
|
-
i =
|
22
|
-
|
23
|
-
|
24
|
-
i += 1
|
25
|
-
end
|
31
|
+
test_slug, i = slug_prefix, 1
|
32
|
+
record_scope = record.new_record? ? record.class.scoped : record.class.where("id != ?", record.id)
|
33
|
+
while not record_scope.where("#{slug_column} = ?", test_slug).count.zero?
|
34
|
+
test_slug = "#{slug_prefix}-#{(i += 1)}"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the slug
|
38
|
+
record[slug_column] = test_slug
|
26
39
|
end
|
27
40
|
|
28
41
|
# Add instance methods to objects using has_unique_slug
|
@@ -33,11 +46,7 @@ module HasUniqueSlug
|
|
33
46
|
# Add configuration mechanism
|
34
47
|
instance_eval <<-EOV
|
35
48
|
def slug_column
|
36
|
-
'#{
|
37
|
-
end
|
38
|
-
|
39
|
-
def title_column
|
40
|
-
'#{title_col}'
|
49
|
+
'#{slug_column}'
|
41
50
|
end
|
42
51
|
EOV
|
43
52
|
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_unique_slug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brendan Stennett
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-13 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Generates a unique slug for use as a drop-in replacement for ids.
|
@@ -35,6 +35,8 @@ files:
|
|
35
35
|
- has_unique_slug.gemspec
|
36
36
|
- lib/has_unique_slug.rb
|
37
37
|
- lib/has_unique_slug/version.rb
|
38
|
+
- spec/has_unique_slug_spec.rb
|
39
|
+
- spec/spec_helper.rb
|
38
40
|
homepage: https://github.com/HuffMoody/has_unique_slug
|
39
41
|
licenses: []
|
40
42
|
|
@@ -68,5 +70,6 @@ rubygems_version: 1.8.10
|
|
68
70
|
signing_key:
|
69
71
|
specification_version: 3
|
70
72
|
summary: Generates a unique slug for use as a drop-in replacement for ids.
|
71
|
-
test_files:
|
72
|
-
|
73
|
+
test_files:
|
74
|
+
- spec/has_unique_slug_spec.rb
|
75
|
+
- spec/spec_helper.rb
|