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 CHANGED
@@ -2,3 +2,4 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in has_unique_slug.gemspec
4
4
  gemspec
5
+ gem 'rspec'
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 in which the slug column is generated from the post title.
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, "-n" is appended onto the end. n starts at 2 and will increment by 1 until a unique slug is found.
19
- If a slug is provided, one will not be generated, however the same rule applies as the above if the slug is not unique.
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 :title, :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 generate the slug
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 :name # Uses the name column to generate the 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
@@ -1,3 +1,3 @@
1
1
  module HasUniqueSlug
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -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(title_col = "title", slug_col = "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
- before_create do |record|
25
+ before_save do |record|
14
26
 
15
27
  # Add a slug if slug doesn't exist
16
- if record[slug_col].blank?
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 = 2
22
- while not record.class.where("#{slug_col} = ?", record[slug_col]).count.zero?
23
- record[slug_col] = "#{record[slug_col]}-#{i}"
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
- '#{slug_col}'
37
- end
38
-
39
- def title_column
40
- '#{title_col}'
49
+ '#{slug_column}'
41
50
  end
42
51
  EOV
43
52
 
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe HasUniqueSlug
4
+ pending "Write test simulating active record"
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'has_unique_slug' # and any other gems you need
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
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: 25
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.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-12 00:00:00 Z
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