slugalicious 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ h1. Slugalicious -- Easy and powerful URL slugging for Rails 3
3
3
  _*(no monkey-patching required)*_
4
4
 
5
5
  | *Author* | Tim Morgan |
6
- | *Version* | 1.2 (Aug 31, 2011) |
6
+ | *Version* | 1.2.1 (Mar 2, 2012) |
7
7
  | *License* | Released under the MIT license. |
8
8
 
9
9
  h2. About
@@ -18,10 +18,8 @@ module Slugalicious
18
18
  MAX_SLUG_LENGTH = 126
19
19
 
20
20
  included do
21
- extend ActiveSupport::Memoizable
22
- memoize :slug, :active_slug?
23
21
  alias_method :to_param, :slug_with_path
24
- has_many :slugs, as: :sluggable
22
+ has_many :slugs, as: :sluggable, dependent: :delete_all
25
23
  end
26
24
 
27
25
  # Methods added to the class when this module is included.
@@ -143,39 +141,36 @@ module Slugalicious
143
141
  end
144
142
  end
145
143
 
146
- # Methods added to instances when this module is included.
147
-
148
- module InstanceMethods
149
-
150
- def slug_object
151
- slugs.loaded? ? slugs.detect(&:active) : slugs.active.first
152
- end
153
- private :slug_object
144
+ def slug_object
145
+ slugs.loaded? ? slugs.detect(&:active) : slugs.active.first
146
+ end
147
+ private :slug_object
154
148
 
155
- # @return [String, nil] The slug for this object, or @nil@ if none has been
156
- # assigned.
149
+ # @return [String, nil] The slug for this object, or @nil@ if none has been
150
+ # assigned.
157
151
 
158
- def slug
159
- Rails.cache.fetch("Slug/#{self.class.to_s}/#{id}/slug") do
160
- slug_object.try(:slug)
161
- end
152
+ def slug
153
+ Rails.cache.fetch("Slug/#{self.class.to_s}/#{id}/slug") do
154
+ slug_object.try(:slug)
162
155
  end
156
+ end
163
157
 
164
- # @return [String, nil] The full slug and path for this object, with scope
165
- # included, or @nil@ if none has been assigned.
158
+ # @return [String, nil] The full slug and path for this object, with scope
159
+ # included, or @nil@ if none has been assigned.
166
160
 
167
- def slug_with_path
168
- Rails.cache.fetch("Slug/#{self.class.to_s}/#{id}/slug_with_path") do
169
- slug_object ? (slug_object.scope.to_s + slug_object.slug) : nil
170
- end
161
+ def slug_with_path
162
+ Rails.cache.fetch("Slug/#{self.class.to_s}/#{id}/slug_with_path") do
163
+ slug_object ? (slug_object.scope.to_s + slug_object.slug) : nil
171
164
  end
165
+ end
172
166
 
173
- # @param [String] slug A slug for this object.
174
- # @return [true, false, nil] @true@ if the slug is the currently active one
175
- # (should not redirect), @false@ if it's inactive (should redirect), and
176
- # @nil@ if it's not a known slug for the object (should 404).
167
+ # @param [String] slug A slug for this object.
168
+ # @return [true, false, nil] @true@ if the slug is the currently active one
169
+ # (should not redirect), @false@ if it's inactive (should redirect), and
170
+ # @nil@ if it's not a known slug for the object (should 404).
177
171
 
178
- def active_slug?(slug)
172
+ def active_slug?(slug)
173
+ @active_slug ||= begin
179
174
  slug = if slugs.loaded? then
180
175
  slugs.detect { |s| s.slug.downcase == slug.downcase }
181
176
  else
@@ -187,60 +182,60 @@ module Slugalicious
187
182
  nil
188
183
  end
189
184
  end
185
+ end
190
186
 
191
- private
192
-
193
- def make_slug
194
- slugs_in_use = if slugs.loaded? then
195
- slugs.map(&:slug)
196
- else
197
- slugs.select(:slug).all.map(&:slug)
198
- end
199
-
200
- # grab a list of all potential slugs derived from the generators
201
- potential_slugs = self.class._slug_procs.map { |slug_proc| slug_proc[self] }.
202
- compact.
203
- map { |slug| self.class._slugifier[slug] }.
204
- map { |slug| slug[0, MAX_SLUG_LENGTH] }
205
- raise "All slug generators returned nil for #{self.inspect}" if potential_slugs.empty?
206
- # include the last-resort slug, trimmed for length
207
- last_resort_append = "#{self.class._slug_id_separator}#{id}"
208
- potential_slugs << "#{potential_slugs.first[0, [ 1, MAX_SLUG_LENGTH - last_resort_append.length ].max]}#{last_resort_append}"[0, MAX_SLUG_LENGTH]
209
- # subtract out blacklisted slugs
210
- potential_slugs -= self.class._slug_blacklist
211
-
212
- # if one of these slugs is already in use, we don't need to change the slug
213
- # instead, activate the one of highest prioirty and we're done
214
- valid_slugs_in_use = potential_slugs & slugs_in_use
215
- unless valid_slugs_in_use.empty?
216
- Slug.transaction do
217
- slugs.update_all(active: false)
218
- slugs.where(slug: valid_slugs_in_use.first).update_all(active: true)
219
- end
220
- return
221
- end
222
-
187
+ private
188
+
189
+ def make_slug
190
+ slugs_in_use = if slugs.loaded? then
191
+ slugs.map(&:slug)
192
+ else
193
+ slugs.select(:slug).all.map(&:slug)
194
+ end
195
+
196
+ # grab a list of all potential slugs derived from the generators
197
+ potential_slugs = self.class._slug_procs.map { |slug_proc| slug_proc[self] }.
198
+ compact.
199
+ map { |slug| self.class._slugifier[slug] }.
200
+ map { |slug| slug[0, MAX_SLUG_LENGTH] }
201
+ raise "All slug generators returned nil for #{self.inspect}" if potential_slugs.empty?
202
+ # include the last-resort slug, trimmed for length
203
+ last_resort_append = "#{self.class._slug_id_separator}#{id}"
204
+ potential_slugs << "#{potential_slugs.first[0, [ 1, MAX_SLUG_LENGTH - last_resort_append.length ].max]}#{last_resort_append}"[0, MAX_SLUG_LENGTH]
205
+ # subtract out blacklisted slugs
206
+ potential_slugs -= self.class._slug_blacklist
207
+
208
+ # if one of these slugs is already in use, we don't need to change the slug
209
+ # instead, activate the one of highest prioirty and we're done
210
+ valid_slugs_in_use = potential_slugs & slugs_in_use
211
+ unless valid_slugs_in_use.empty?
223
212
  Slug.transaction do
224
- # grab a list of all the slugs we can't use
225
- scope = Slug.select(:slug).where(sluggable_type: self.class.to_s, slug: potential_slugs)
226
- if self.class._slug_scope then
227
- scope = scope.where(scope: self.class._slug_scope[self])
228
- end
229
- taken_slug_objects = scope.all
230
-
231
- # subtract them out from all the potential slugs to make the available slugs
232
- available_slugs = potential_slugs - taken_slug_objects.map(&:slug)
233
- # no slugs available? nothing much else we can do
234
- raise "Couldn't find a slug for #{self.inspect}; tried #{potential_slugs.join(', ')}" if available_slugs.empty?
235
-
236
213
  slugs.update_all(active: false)
237
- Slug.create!(sluggable: self,
238
- slug: available_slugs.first,
239
- active: true,
240
- scope: self.class._slug_scope.try(:call, self))
214
+ slugs.where(slug: valid_slugs_in_use.first).update_all(active: true)
241
215
  end
216
+ return
217
+ end
242
218
 
243
- unmemoize_all
219
+ Slug.transaction do
220
+ # grab a list of all the slugs we can't use
221
+ scope = Slug.select(:slug).where(sluggable_type: self.class.to_s, slug: potential_slugs)
222
+ if self.class._slug_scope then
223
+ scope = scope.where(scope: self.class._slug_scope[self])
224
+ end
225
+ taken_slug_objects = scope.all
226
+
227
+ # subtract them out from all the potential slugs to make the available slugs
228
+ available_slugs = potential_slugs - taken_slug_objects.map(&:slug)
229
+ # no slugs available? nothing much else we can do
230
+ raise "Couldn't find a slug for #{self.inspect}; tried #{potential_slugs.join(', ')}" if available_slugs.empty?
231
+
232
+ slugs.update_all(active: false)
233
+ Slug.create!(sluggable: self,
234
+ slug: available_slugs.first,
235
+ active: true,
236
+ scope: self.class._slug_scope.try(:call, self))
244
237
  end
238
+
239
+ @active_slug = nil
245
240
  end
246
241
  end
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{slugalicious}
8
- s.version = "1.2.0"
7
+ s.name = "slugalicious"
8
+ s.version = "1.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{Tim Morgan}]
12
- s.date = %q{2011-08-31}
13
- s.description = %q{Slugalicious adds simple and powerful slugging to your ActiveRecord models.}
14
- s.email = %q{git@timothymorgan.info}
11
+ s.authors = ["Tim Morgan"]
12
+ s.date = "2012-03-02"
13
+ s.description = "Slugalicious adds simple and powerful slugging to your ActiveRecord models."
14
+ s.email = "git@timothymorgan.info"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
17
  "README.textile"
@@ -25,11 +25,11 @@ Gem::Specification.new do |s|
25
25
  "templates/create_slugs.rb",
26
26
  "templates/slug.rb"
27
27
  ]
28
- s.homepage = %q{http://github.com/riscfuture/slugalicious}
29
- s.require_paths = [%q{lib}]
28
+ s.homepage = "http://github.com/riscfuture/slugalicious"
29
+ s.require_paths = ["lib"]
30
30
  s.required_ruby_version = Gem::Requirement.new(">= 1.9")
31
- s.rubygems_version = %q{1.8.9}
32
- s.summary = %q{Easy-to-use and powerful slugging for Rails 3}
31
+ s.rubygems_version = "1.8.17"
32
+ s.summary = "Easy-to-use and powerful slugging for Rails 3"
33
33
 
34
34
  if s.respond_to? :specification_version then
35
35
  s.specification_version = 3
@@ -1,5 +1,5 @@
1
1
  class CreateSlugs < ActiveRecord::Migration
2
- def self.up
2
+ def change
3
3
  create_table :slugs do |t|
4
4
  t.belongs_to :sluggable, polymorphic: true, null: false
5
5
  t.boolean :active, null: false, default: true
@@ -13,8 +13,4 @@ class CreateSlugs < ActiveRecord::Migration
13
13
  t.index [ :sluggable_type, :scope, :slug ], unique: true, name: 'slugs_unique'
14
14
  end
15
15
  end
16
-
17
- def self.down
18
- drop_table :slugs
19
- end
20
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slugalicious
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-31 00:00:00.000000000Z
12
+ date: 2012-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &2169205560 !ruby/object:Gem::Requirement
16
+ requirement: &70280246265900 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2169205560
24
+ version_requirements: *70280246265900
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: stringex
27
- requirement: &2169205060 !ruby/object:Gem::Requirement
27
+ requirement: &70280246265420 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2169205060
35
+ version_requirements: *70280246265420
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &2169195740 !ruby/object:Gem::Requirement
38
+ requirement: &70280246264940 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2169195740
46
+ version_requirements: *70280246264940
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: yard
49
- requirement: &2169195200 !ruby/object:Gem::Requirement
49
+ requirement: &70280246264460 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2169195200
57
+ version_requirements: *70280246264460
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: RedCloth
60
- requirement: &2169194540 !ruby/object:Gem::Requirement
60
+ requirement: &70280246263980 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2169194540
68
+ version_requirements: *70280246263980
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sqlite3
71
- requirement: &2169193980 !ruby/object:Gem::Requirement
71
+ requirement: &70280246263500 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2169193980
79
+ version_requirements: *70280246263500
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &2169193380 !ruby/object:Gem::Requirement
82
+ requirement: &70280246263020 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2169193380
90
+ version_requirements: *70280246263020
91
91
  description: Slugalicious adds simple and powerful slugging to your ActiveRecord models.
92
92
  email: git@timothymorgan.info
93
93
  executables: []
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  version: '0'
124
124
  requirements: []
125
125
  rubyforge_project:
126
- rubygems_version: 1.8.9
126
+ rubygems_version: 1.8.17
127
127
  signing_key:
128
128
  specification_version: 3
129
129
  summary: Easy-to-use and powerful slugging for Rails 3