has_unique_slug 0.1.1 → 0.1.2
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.
- 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
|