friendly_id 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|