slugalicious 1.2.0 → 1.2.1
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/README.textile +1 -1
- data/lib/slugalicious.rb +72 -77
- data/slugalicious.gemspec +10 -10
- data/templates/create_slugs.rb +1 -5
- metadata +17 -17
data/README.textile
CHANGED
data/lib/slugalicious.rb
CHANGED
@@ -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
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
156
|
-
|
149
|
+
# @return [String, nil] The slug for this object, or @nil@ if none has been
|
150
|
+
# assigned.
|
157
151
|
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
165
|
-
|
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
|
-
|
168
|
-
|
169
|
-
|
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
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
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
|
-
|
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
|
data/slugalicious.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "1.2.
|
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 = [
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
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 =
|
29
|
-
s.require_paths = [
|
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 =
|
32
|
-
s.summary =
|
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
|
data/templates/create_slugs.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class CreateSlugs < ActiveRecord::Migration
|
2
|
-
def
|
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.
|
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:
|
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: &
|
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: *
|
24
|
+
version_requirements: *70280246265900
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: stringex
|
27
|
-
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: *
|
35
|
+
version_requirements: *70280246265420
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jeweler
|
38
|
-
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: *
|
46
|
+
version_requirements: *70280246264940
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: yard
|
49
|
-
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: *
|
57
|
+
version_requirements: *70280246264460
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: RedCloth
|
60
|
-
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: *
|
68
|
+
version_requirements: *70280246263980
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: sqlite3
|
71
|
-
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: *
|
79
|
+
version_requirements: *70280246263500
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rspec
|
82
|
-
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: *
|
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.
|
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
|