mongoid_slug 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mongoid/slug.rb CHANGED
@@ -24,8 +24,7 @@ module Mongoid #:nodoc:
24
24
 
25
25
  # Sets one ore more fields as source of slug.
26
26
  #
27
- # Takes a list of one or more fields to slug and an optional options
28
- # hash.
27
+ # Takes a list of fields to slug and an optional options hash.
29
28
  #
30
29
  # The options hash respects the following members:
31
30
  #
@@ -63,14 +62,14 @@ module Mongoid #:nodoc:
63
62
  options = fields.extract_options!
64
63
  self.slug_scope = options[:scope]
65
64
  self.slug_name = options[:as] || :slug
66
- self.slugged_fields = fields
65
+ self.slugged_fields = fields.map(&:to_s)
67
66
 
68
67
  self.slug_builder =
69
68
  if block_given?
70
69
  block
71
70
  else
72
71
  lambda do |doc|
73
- slugged_fields.map { |f| doc.send(f) }.join(',')
72
+ slugged_fields.map { |f| doc.read_attribute(f) }.join(',')
74
73
  end
75
74
  end
76
75
 
@@ -107,23 +106,31 @@ module Mongoid #:nodoc:
107
106
 
108
107
  # Returns the slug.
109
108
  def to_param
110
- self.send(slug_name)
109
+ read_attribute(slug_name)
111
110
  end
112
111
 
113
112
  private
114
113
 
115
- def build_slug
116
- ("#{slug_builder.call(self)} #{@slug_counter}").to_url
117
- end
118
-
119
114
  def find_unique_slug
120
- slug = build_slug
121
- if unique_slug?(slug)
122
- slug
123
- else
124
- increment_slug_counter
125
- find_unique_slug
115
+ slug = slug_builder.call(self).to_url
116
+
117
+ # Regular expression that matches slug, slug-1, slug-2, ... slug-n
118
+ # If slug_name field was indexed, MongoDB will utilize that index to
119
+ # match /^.../ pattern
120
+ pattern = /^#{Regexp.escape(slug)}(?:-\d+)?$/
121
+
122
+ # Get the maximum counter slug
123
+ max_counter_slug = uniqueness_scope.only(slug_name).
124
+ where(slug_name => pattern, :_id.ne => _id).
125
+ order_by([slug_name, :desc]).first.try(:read_attribute, slug_name)
126
+
127
+ if max_counter_slug
128
+ max_counter = max_counter_slug.match(/-(\d+)$/).try(:[], 1).to_i
129
+ # Use max_counter + 1 as unique counter
130
+ slug += "-#{max_counter + 1}"
126
131
  end
132
+
133
+ slug
127
134
  end
128
135
 
129
136
  def generate_slug
@@ -133,21 +140,11 @@ module Mongoid #:nodoc:
133
140
  end
134
141
 
135
142
  def generate_slug!
136
- self.send("#{slug_name}=", find_unique_slug)
137
- end
138
-
139
- def increment_slug_counter
140
- @slug_counter = (@slug_counter.to_i + 1).to_s
143
+ write_attribute(slug_name, find_unique_slug)
141
144
  end
142
145
 
143
146
  def slugged_fields_changed?
144
- slugged_fields.any? { |f| self.send("#{f}_changed?") }
145
- end
146
-
147
- def unique_slug?(slug)
148
- uniqueness_scope.where(slug_name => slug).
149
- reject { |doc| doc.id == self.id }.
150
- empty?
147
+ slugged_fields.any? { |f| attribute_changed?(f) }
151
148
  end
152
149
 
153
150
  def uniqueness_scope
@@ -1,5 +1,5 @@
1
1
  module Mongoid #:nodoc:
2
2
  module Slug
3
- VERSION = '0.7.0'
3
+ VERSION = '0.7.1'
4
4
  end
5
5
  end
@@ -146,6 +146,13 @@ module Mongoid
146
146
  :first_name => author.first_name,
147
147
  :last_name => author.last_name)
148
148
  dup.to_param.should eql 'gilles-deleuze-1'
149
+
150
+ dup2 = Author.create(
151
+ :first_name => author.first_name,
152
+ :last_name => author.last_name)
153
+
154
+ dup.save
155
+ dup2.to_param.should eql 'gilles-deleuze-2'
149
156
  end
150
157
 
151
158
  it "does not update slug if slugged fields have changed but generated slug is identical" do
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mongoid_slug
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.7.0
5
+ version: 0.7.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Paper Cavalier
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-31 00:00:00 +01:00
13
+ date: 2011-04-02 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency