friendly_id 2.2.1 → 2.2.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/History.txt +5 -0
- data/Manifest.txt +5 -0
- data/lib/friendly_id/tasks.rb +57 -0
- data/lib/friendly_id/version.rb +1 -1
- data/lib/tasks/friendly_id.rake +11 -34
- data/test/cached_slug_test.rb +5 -2
- data/test/custom_slug_normalizer_test.rb +5 -2
- data/test/models/city.rb +4 -0
- data/test/models/district.rb +3 -0
- data/test/non_slugged_test.rb +5 -2
- data/test/scoped_model_test.rb +7 -4
- data/test/slug_test.rb +1 -1
- data/test/slugged_model_test.rb +5 -2
- data/test/sti_test.rb +5 -2
- data/test/tasks_test.rb +106 -0
- metadata +8 -2
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -16,13 +16,17 @@ lib/friendly_id/non_sluggable_instance_methods.rb
|
|
16
16
|
lib/friendly_id/slug.rb
|
17
17
|
lib/friendly_id/sluggable_class_methods.rb
|
18
18
|
lib/friendly_id/sluggable_instance_methods.rb
|
19
|
+
lib/friendly_id/tasks.rb
|
19
20
|
lib/friendly_id/version.rb
|
20
21
|
lib/tasks/friendly_id.rake
|
21
22
|
lib/tasks/friendly_id.rb
|
23
|
+
test/cached_slug_test.rb
|
22
24
|
test/contest.rb
|
23
25
|
test/custom_slug_normalizer_test.rb
|
24
26
|
test/models/book.rb
|
27
|
+
test/models/city.rb
|
25
28
|
test/models/country.rb
|
29
|
+
test/models/district.rb
|
26
30
|
test/models/event.rb
|
27
31
|
test/models/novel.rb
|
28
32
|
test/models/person.rb
|
@@ -35,4 +39,5 @@ test/scoped_model_test.rb
|
|
35
39
|
test/slug_test.rb
|
36
40
|
test/slugged_model_test.rb
|
37
41
|
test/sti_test.rb
|
42
|
+
test/tasks_test.rb
|
38
43
|
test/test_helper.rb
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module FriendlyId
|
2
|
+
class Tasks
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def make_slugs(klass, options = {})
|
6
|
+
klass = parse_class_name(klass)
|
7
|
+
validate_uses_slugs(klass)
|
8
|
+
options = {:limit => 100, :include => :slugs, :order => "#{klass.table_name}.id ASC",
|
9
|
+
:conditions => "slugs.id IS NULL"}.merge(options)
|
10
|
+
while records = klass.find(:all, options) do
|
11
|
+
break if records.size == 0
|
12
|
+
records.each do |r|
|
13
|
+
r.save!
|
14
|
+
yield(r) if block_given?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete_slugs_for(klass)
|
20
|
+
klass = parse_class_name(klass)
|
21
|
+
validate_uses_slugs(klass)
|
22
|
+
Slug.destroy_all(["sluggable_type = ?", klass.to_s])
|
23
|
+
if klass.friendly_id_options[:cache_column]
|
24
|
+
klass.update_all("#{klass.friendly_id_options[:cache_column]} = NULL")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete_old_slugs(days = nil, class_name = nil)
|
29
|
+
days = days.blank? ? 45 : days.to_i
|
30
|
+
klass = class_name.blank? ? nil : parse_class_name(class_name.to_s)
|
31
|
+
conditions = ["created_at < ?", DateTime.now - days.days]
|
32
|
+
if klass
|
33
|
+
conditions[0] << " AND sluggable_type = ?"
|
34
|
+
conditions << klass.to_s
|
35
|
+
end
|
36
|
+
slugs = Slug.find :all, :conditions => conditions
|
37
|
+
slugs.each { |s| s.destroy unless s.is_most_recent? }
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_class_name(class_name)
|
41
|
+
return class_name if class_name.class == Class
|
42
|
+
if (class_name.split('::').size > 1)
|
43
|
+
class_name.split('::').inject(Kernel) {|scope, const_name| scope.const_get(const_name)}
|
44
|
+
else
|
45
|
+
Object.const_get(class_name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def validate_uses_slugs(klass)
|
52
|
+
raise "Class '%s' doesn't use slugs" % klass.to_s unless klass.friendly_id_options[:use_slug]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/friendly_id/version.rb
CHANGED
data/lib/tasks/friendly_id.rake
CHANGED
@@ -1,50 +1,27 @@
|
|
1
|
-
|
1
|
+
require "friendly_id/tasks"
|
2
2
|
|
3
3
|
namespace :friendly_id do
|
4
4
|
desc "Make slugs for a model."
|
5
5
|
task :make_slugs => :environment do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
while records = sluggable_class.find(:all, :include => :slugs, :conditions => "slugs.id IS NULL", :limit => 1000) do
|
11
|
-
break if records.size == 0
|
12
|
-
records.each do |r|
|
13
|
-
r.send(:set_slug)
|
14
|
-
r.save!
|
15
|
-
puts "#{sluggable_class.to_s}(#{r.id}) friendly_id set to \"#{r.slug.name}\""
|
16
|
-
end
|
6
|
+
validate_model_given
|
7
|
+
FriendlyId::Tasks.make_slugs(ENV["MODEL"]) do |r|
|
8
|
+
puts "%s(%d) friendly_id set to '%s'" % [r.class.to_s, r.id, r.slug.name]
|
17
9
|
end
|
18
10
|
end
|
19
11
|
|
20
12
|
desc "Regenereate slugs for a model."
|
21
13
|
task :redo_slugs => :environment do
|
22
|
-
|
23
|
-
|
24
|
-
raise "Class \"#{sluggable_class.to_s}\" doesn't appear to be using slugs"
|
25
|
-
end
|
26
|
-
Slug.destroy_all(["sluggable_type = ?", sluggable_class.to_s])
|
14
|
+
validate_model_given
|
15
|
+
FriendlyId::Tasks.delete_slugs_for(ENV["MODEL"])
|
27
16
|
Rake::Task["friendly_id:make_slugs"].invoke
|
28
17
|
end
|
29
18
|
|
30
|
-
desc "Kill obsolete slugs older than 45 days."
|
19
|
+
desc "Kill obsolete slugs older than DAYS=45 days."
|
31
20
|
task :remove_old_slugs => :environment do
|
32
|
-
|
33
|
-
@days = 45
|
34
|
-
else
|
35
|
-
@days = ENV["DAYS"].to_i
|
36
|
-
end
|
37
|
-
slugs = Slug.find(:all, :conditions => ["created_at < ?", DateTime.now - @days.days])
|
38
|
-
slugs.each do |s|
|
39
|
-
s.destroy if !s.is_most_recent?
|
40
|
-
end
|
21
|
+
FriendlyId::Task.delete_old_slugs(ENV["DAYS"], ENV["MODEL"])
|
41
22
|
end
|
42
23
|
end
|
43
24
|
|
44
|
-
def
|
45
|
-
if
|
46
|
-
|
47
|
-
else
|
48
|
-
Object.const_get(ENV["MODEL"])
|
49
|
-
end
|
50
|
-
end
|
25
|
+
def validate_model_given
|
26
|
+
raise 'USAGE: rake friendly_id:make_slugs MODEL=MyModelName' if ENV["MODEL"].nil?
|
27
|
+
end
|
data/test/cached_slug_test.rb
CHANGED
@@ -8,12 +8,15 @@ class CachedSlugModelTest < Test::Unit::TestCase
|
|
8
8
|
context "A slugged model with a cached_slugs column" do
|
9
9
|
|
10
10
|
setup do
|
11
|
-
City.delete_all
|
12
|
-
Slug.delete_all
|
13
11
|
@paris = City.new(:name => "Paris")
|
14
12
|
@paris.save!
|
15
13
|
end
|
16
14
|
|
15
|
+
teardown do
|
16
|
+
City.delete_all
|
17
|
+
Slug.delete_all
|
18
|
+
end
|
19
|
+
|
17
20
|
should "have a slug" do
|
18
21
|
assert_not_nil @paris.slug
|
19
22
|
end
|
@@ -8,6 +8,9 @@ class CustomSlugNormalizerTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
setup do
|
10
10
|
Thing.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :name, :use_slug => true)
|
11
|
+
end
|
12
|
+
|
13
|
+
teardown do
|
11
14
|
Thing.delete_all
|
12
15
|
Slug.delete_all
|
13
16
|
end
|
@@ -29,7 +32,7 @@ class CustomSlugNormalizerTest < Test::Unit::TestCase
|
|
29
32
|
Thing.create!(:name => "test")
|
30
33
|
end
|
31
34
|
end
|
32
|
-
|
35
|
+
|
33
36
|
end
|
34
37
|
|
35
|
-
end
|
38
|
+
end
|
data/test/models/city.rb
ADDED
data/test/non_slugged_test.rb
CHANGED
@@ -7,10 +7,13 @@ class NonSluggedTest < Test::Unit::TestCase
|
|
7
7
|
context "A non-slugged model with default FriendlyId options" do
|
8
8
|
|
9
9
|
setup do
|
10
|
-
User.delete_all
|
11
10
|
@user = User.create!(:login => "joe", :email => "joe@example.org")
|
12
11
|
end
|
13
12
|
|
13
|
+
teardown do
|
14
|
+
User.delete_all
|
15
|
+
end
|
16
|
+
|
14
17
|
should "have friendly_id options" do
|
15
18
|
assert_not_nil User.friendly_id_options
|
16
19
|
end
|
@@ -95,4 +98,4 @@ class NonSluggedTest < Test::Unit::TestCase
|
|
95
98
|
|
96
99
|
end
|
97
100
|
|
98
|
-
end
|
101
|
+
end
|
data/test/scoped_model_test.rb
CHANGED
@@ -7,15 +7,18 @@ class ScopedModelTest < Test::Unit::TestCase
|
|
7
7
|
context "A slugged model that uses a scope" do
|
8
8
|
|
9
9
|
setup do
|
10
|
-
Person.delete_all
|
11
|
-
Country.delete_all
|
12
|
-
Slug.delete_all
|
13
10
|
@usa = Country.create!(:name => "USA")
|
14
11
|
@canada = Country.create!(:name => "Canada")
|
15
12
|
@person = Person.create!(:name => "John Smith", :country => @usa)
|
16
13
|
@person2 = Person.create!(:name => "John Smith", :country => @canada)
|
17
14
|
end
|
18
15
|
|
16
|
+
teardown do
|
17
|
+
Person.delete_all
|
18
|
+
Country.delete_all
|
19
|
+
Slug.delete_all
|
20
|
+
end
|
21
|
+
|
19
22
|
should "find all scoped records without scope" do
|
20
23
|
assert_equal 2, Person.find(:all, @person.friendly_id).size
|
21
24
|
end
|
@@ -50,4 +53,4 @@ class ScopedModelTest < Test::Unit::TestCase
|
|
50
53
|
|
51
54
|
end
|
52
55
|
|
53
|
-
end
|
56
|
+
end
|
data/test/slug_test.rb
CHANGED
data/test/slugged_model_test.rb
CHANGED
@@ -8,12 +8,15 @@ class SluggedModelTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
setup do
|
10
10
|
Post.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
|
11
|
+
@post = Post.new :title => "Test post", :content => "Test content", :published => true
|
12
|
+
@post.save!
|
13
|
+
end
|
14
|
+
|
15
|
+
teardown do
|
11
16
|
Post.delete_all
|
12
17
|
Person.delete_all
|
13
18
|
Slug.delete_all
|
14
19
|
Thing.delete_all
|
15
|
-
@post = Post.new :title => "Test post", :content => "Test content", :published => true
|
16
|
-
@post.save!
|
17
20
|
end
|
18
21
|
|
19
22
|
should "have friendly_id options" do
|
data/test/sti_test.rb
CHANGED
@@ -8,12 +8,15 @@ class STIModelTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
setup do
|
10
10
|
Novel.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
|
11
|
-
Novel.delete_all
|
12
|
-
Slug.delete_all
|
13
11
|
@novel = Novel.new :title => "Test novel"
|
14
12
|
@novel.save!
|
15
13
|
end
|
16
14
|
|
15
|
+
teardown do
|
16
|
+
Novel.delete_all
|
17
|
+
Slug.delete_all
|
18
|
+
end
|
19
|
+
|
17
20
|
should "have a slug" do
|
18
21
|
assert_not_nil @novel.slug
|
19
22
|
end
|
data/test/tasks_test.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require "friendly_id/tasks"
|
3
|
+
require "mocha"
|
4
|
+
|
5
|
+
class TasksTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "FriendlyId tasks" do
|
8
|
+
|
9
|
+
should "parse a top-level class name and return a class" do
|
10
|
+
assert_equal String, FriendlyId::Tasks.parse_class_name("String")
|
11
|
+
end
|
12
|
+
|
13
|
+
should "parse a namespaced class name and return a class" do
|
14
|
+
assert_equal Test::Unit, FriendlyId::Tasks.parse_class_name("Test::Unit")
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
context "The 'make slugs' task" do
|
20
|
+
|
21
|
+
setup do
|
22
|
+
City.create! :name => "Buenos Aires"
|
23
|
+
City.create! :name => "Rio de Janeiro"
|
24
|
+
City.create! :name => "Tokyo"
|
25
|
+
City.create! :name => "Nairobi"
|
26
|
+
Slug.delete_all
|
27
|
+
end
|
28
|
+
|
29
|
+
teardown do
|
30
|
+
City.delete_all
|
31
|
+
Slug.delete_all
|
32
|
+
end
|
33
|
+
|
34
|
+
should "make one slug per model" do
|
35
|
+
assert_equal 0, Slug.count
|
36
|
+
FriendlyId::Tasks.make_slugs("City")
|
37
|
+
assert_equal 4, Slug.count
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "The 'delete_slugs_for' task" do
|
43
|
+
|
44
|
+
setup do
|
45
|
+
@post = Post.create! :title => "Slugs Considered Harmful"
|
46
|
+
@city = City.create! :name => "Buenos Aires"
|
47
|
+
end
|
48
|
+
|
49
|
+
teardown do
|
50
|
+
Post.delete_all
|
51
|
+
City.delete_all
|
52
|
+
Slug.delete_all
|
53
|
+
end
|
54
|
+
|
55
|
+
should "Delete only slugs for the specified model" do
|
56
|
+
assert_equal 2, Slug.count
|
57
|
+
FriendlyId::Tasks.delete_slugs_for("City")
|
58
|
+
assert_equal 1, Slug.count
|
59
|
+
end
|
60
|
+
|
61
|
+
should "set the cached_slug column to NULL" do
|
62
|
+
FriendlyId::Tasks.delete_slugs_for("City")
|
63
|
+
@city.reload
|
64
|
+
assert_nil @city.my_slug
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
context "The 'delete_old_slugs' task" do
|
70
|
+
|
71
|
+
setup do
|
72
|
+
@post = Post.create! :title => "Slugs Considered Harmful"
|
73
|
+
@city = City.create! :name => "Buenos Aires"
|
74
|
+
City.connection.execute "UPDATE slugs SET created_at = '%s' WHERE id = %d" % [
|
75
|
+
45.days.ago.strftime("%Y-%m-%d"), @city.slug.id]
|
76
|
+
@city.name = "Ciudad de Buenos Aires"
|
77
|
+
@city.save!
|
78
|
+
end
|
79
|
+
|
80
|
+
teardown do
|
81
|
+
Post.delete_all
|
82
|
+
City.delete_all
|
83
|
+
Slug.delete_all
|
84
|
+
end
|
85
|
+
|
86
|
+
should "delete slugs older than 45 days by default" do
|
87
|
+
assert_equal 3, Slug.count
|
88
|
+
FriendlyId::Tasks.delete_old_slugs
|
89
|
+
assert_equal 2, Slug.count
|
90
|
+
end
|
91
|
+
|
92
|
+
should "respect the days argument" do
|
93
|
+
assert_equal 3, Slug.count
|
94
|
+
FriendlyId::Tasks.delete_old_slugs(100)
|
95
|
+
assert_equal 3, Slug.count
|
96
|
+
end
|
97
|
+
|
98
|
+
should "respect the class argument" do
|
99
|
+
assert_equal 3, Slug.count
|
100
|
+
FriendlyId::Tasks.delete_old_slugs(1, "Post")
|
101
|
+
assert_equal 3, Slug.count
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: friendly_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Norman Clarke
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-10-
|
14
|
+
date: 2009-10-26 00:00:00 -03:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -96,13 +96,17 @@ files:
|
|
96
96
|
- lib/friendly_id/slug.rb
|
97
97
|
- lib/friendly_id/sluggable_class_methods.rb
|
98
98
|
- lib/friendly_id/sluggable_instance_methods.rb
|
99
|
+
- lib/friendly_id/tasks.rb
|
99
100
|
- lib/friendly_id/version.rb
|
100
101
|
- lib/tasks/friendly_id.rake
|
101
102
|
- lib/tasks/friendly_id.rb
|
103
|
+
- test/cached_slug_test.rb
|
102
104
|
- test/contest.rb
|
103
105
|
- test/custom_slug_normalizer_test.rb
|
104
106
|
- test/models/book.rb
|
107
|
+
- test/models/city.rb
|
105
108
|
- test/models/country.rb
|
109
|
+
- test/models/district.rb
|
106
110
|
- test/models/event.rb
|
107
111
|
- test/models/novel.rb
|
108
112
|
- test/models/person.rb
|
@@ -115,6 +119,7 @@ files:
|
|
115
119
|
- test/slug_test.rb
|
116
120
|
- test/slugged_model_test.rb
|
117
121
|
- test/sti_test.rb
|
122
|
+
- test/tasks_test.rb
|
118
123
|
- test/test_helper.rb
|
119
124
|
has_rdoc: true
|
120
125
|
homepage: http://friendly-id.rubyforge.org/
|
@@ -153,3 +158,4 @@ test_files:
|
|
153
158
|
- test/slug_test.rb
|
154
159
|
- test/slugged_model_test.rb
|
155
160
|
- test/sti_test.rb
|
161
|
+
- test/tasks_test.rb
|