public
Fork of technoweenie/permalink_fu
Description: ActiveRecord plugin for automatically converting fields to permalinks.
Clone URL: git://github.com/github/permalink_fu.git
append incrementing numbers for duplicate guids

git-svn-id: 
http://svn.techno-weenie.net/projects/plugins/permalink_fu@2993 
567b1171-46fb-0310-a4c9-b4bef9110e78
technoweenie (author)
Mon Oct 15 14:19:36 -0700 2007
commit  dd229ee5509da7e3159075ce988a77156a316a8e
tree    040d110c031cf2aae62b9e4dbcb6448e20c7fee4
parent  8f215a0ec831685c124c784ad618559f4a6ae9ea
...
1
2
 
3
...
 
1
2
3
0
@@ -1 +1 @@
0
-ActiveRecord::Base.send :extend, PermalinkFu
0
\ No newline at end of file
0
+ActiveRecord::Base.send :include, PermalinkFu
0
\ No newline at end of file
...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
36
37
...
14
15
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
0
@@ -14,24 +14,61 @@ module PermalinkFu
0
     end
0
   end
0
   
0
- # Specifies the given field(s) as a permalink, meaning it is passed through PermalinkFu.escape and set to the permalink_field. This
0
- # is done
0
- #
0
- # class Foo < ActiveRecord::Base
0
- # # stores permalink form of #title to the #permalink attribute
0
- # has_permalink :title
0
- #
0
- # # stores a permalink form of "#{category}-#{title}" to the #permalink attribute
0
- #
0
- # has_permalink [:category, :title]
0
- #
0
- # # stores permalink form of #title to the #category_permalink attribute
0
- # has_permalink [:category, :title], :category_permalink
0
- # end
0
- #
0
- def has_permalink(attr_names = [], permalink_field = nil)
0
- permalink_field ||= 'permalink'
0
- before_validation { |record| record.send("#{permalink_field}=", Array(attr_names).collect { |attr_name| PermalinkFu.escape(record.send(attr_name).to_s) }.join('-')) if record.send(permalink_field).to_s.empty? }
0
+ def self.included(base)
0
+ base.extend ClassMethods
0
+ class << base
0
+ attr_accessor :permalink_attributes
0
+ attr_accessor :permalink_field
0
+ end
0
+ end
0
+
0
+ module ClassMethods
0
+ # Specifies the given field(s) as a permalink, meaning it is passed through PermalinkFu.escape and set to the permalink_field. This
0
+ # is done
0
+ #
0
+ # class Foo < ActiveRecord::Base
0
+ # # stores permalink form of #title to the #permalink attribute
0
+ # has_permalink :title
0
+ #
0
+ # # stores a permalink form of "#{category}-#{title}" to the #permalink attribute
0
+ #
0
+ # has_permalink [:category, :title]
0
+ #
0
+ # # stores permalink form of #title to the #category_permalink attribute
0
+ # has_permalink [:category, :title], :category_permalink
0
+ #
0
+ #
0
+ # end
0
+ #
0
+ def has_permalink(attr_names = [], permalink_field = 'permalink')
0
+ self.permalink_attributes = Array(attr_names)
0
+ self.permalink_field = permalink_field
0
+ before_validation :create_unique_permalink
0
+ end
0
+ end
0
+
0
+protected
0
+ def create_unique_permalink
0
+ if send(self.class.permalink_field).to_s.empty?
0
+ send("#{self.class.permalink_field}=", create_permalink_for(self.class.permalink_attributes))
0
+ end
0
+ base = send(self.class.permalink_field)
0
+ counter = 1
0
+ conditions = ["#{self.class.permalink_field} = ?", send(self.class.permalink_field)]
0
+ unless new_record?
0
+ conditions.first << " and id != ?"
0
+ conditions << id
0
+ end
0
+ while self.class.count(:all, :conditions => conditions) > 0
0
+ conditions[1] = "#{base}-#{counter += 1}"
0
+ send("#{self.class.permalink_field}=", conditions[1])
0
+ end
0
+ end
0
+
0
+ def create_permalink_for(attr_names)
0
+ attr_names.collect do |attr_name|
0
+ PermalinkFu.escape(send(attr_name).to_s)
0
+ end.join('-')
0
   end
0
 end
0
 
...
2
3
4
5
 
 
6
7
8
9
10
 
 
 
 
 
 
 
 
 
 
 
11
12
13
14
 
15
16
17
 
 
 
 
 
18
19
20
21
22
 
 
23
24
25
26
27
28
 
 
 
 
 
 
29
30
31
32
 
33
34
 
 
 
 
35
36
37
...
68
69
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
...
2
3
4
 
5
6
7
8
9
 
 
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
24
25
26
 
27
28
29
30
31
32
33
34
35
 
36
37
38
39
40
41
 
 
42
43
44
45
46
47
48
49
50
 
51
52
53
54
55
56
57
58
59
60
...
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
0
@@ -2,36 +2,59 @@ require 'test/unit'
0
 require File.join(File.dirname(__FILE__), '../lib/permalink_fu')
0
 
0
 class MockModel
0
- extend PermalinkFu
0
+ include PermalinkFu
0
+ attr_accessor :id
0
   attr_accessor :title
0
   attr_accessor :permalink
0
   
0
- def self.before_validation(&block)
0
- @@validation = block
0
+ def self.count(whatever, options = {})
0
+ if options[:conditions][1] == 'foo' || options[:conditions][1] == 'bar' ||
0
+ (options[:conditions][1] == 'bar-2' && options[:conditions][2] != 2)
0
+ 1
0
+ else
0
+ 0
0
+ end
0
+ end
0
+
0
+ def self.before_validation(method)
0
+ @@validation = method
0
   end
0
   
0
   def validate
0
- @@validation.call self
0
+ send @@validation
0
     permalink
0
   end
0
-
0
+
0
+ def new_record?
0
+ @id.nil?
0
+ end
0
+
0
   has_permalink :title
0
 end
0
 
0
 class MockModelExtra
0
- extend PermalinkFu
0
+ include PermalinkFu
0
+ attr_accessor :id
0
   attr_accessor :title
0
   attr_accessor :extra
0
   attr_accessor :permalink
0
 
0
- def self.before_validation(&block)
0
- @@validation = block
0
+ def self.count(*args)
0
+ 0
0
+ end
0
+
0
+ def self.before_validation(method)
0
+ @@validation = method
0
   end
0
 
0
   def validate
0
- @@validation.call self
0
+ send @@validation
0
     permalink
0
   end
0
+
0
+ def new_record?
0
+ !@id.nil?
0
+ end
0
 
0
   has_permalink [:title, :extra]
0
 end
0
@@ -68,4 +91,23 @@ class PermalinkFuTest < Test::Unit::TestCase
0
       end
0
     end
0
   end
0
+
0
+ def test_should_create_unique_permalink
0
+ @m = MockModel.new
0
+ @m.permalink = 'foo'
0
+ @m.validate
0
+ assert_equal 'foo-2', @m.permalink
0
+
0
+ @m.permalink = 'bar'
0
+ @m.validate
0
+ assert_equal 'bar-3', @m.permalink
0
+ end
0
+
0
+ def test_should_not_check_itself_for_unique_permalink
0
+ @m = MockModel.new
0
+ @m.id = 2
0
+ @m.permalink = 'bar-2'
0
+ @m.validate
0
+ assert_equal 'bar-2', @m.permalink
0
+ end
0
 end

Comments

    No one has commented yet.