mongoid_slug 0.1.0 → 0.2.0
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.rdoc +3 -1
- data/lib/mongoid_slug.rb +19 -9
- data/spec/models/author.rb +7 -0
- data/spec/models/book.rb +4 -2
- data/spec/models/publisher.rb +9 -0
- data/spec/models/subject.rb +7 -0
- data/spec/unit/mongoid_slug_spec.rb +137 -23
- metadata +10 -4
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Mongoid Slug
|
2
2
|
|
3
|
-
This gem generates a URL slug/permalink based on a field in a Mongoid model.
|
3
|
+
This gem generates a URL slug/permalink based on a field or set of fields in a Mongoid model.
|
4
4
|
|
5
5
|
class Book
|
6
6
|
include Mongoid::Document
|
@@ -15,3 +15,5 @@ This gem generates a URL slug/permalink based on a field in a Mongoid model.
|
|
15
15
|
>> book.update_attributes(:title => "Anti Oedipus")
|
16
16
|
>> book.to_param
|
17
17
|
"anti-oedipus"
|
18
|
+
>> Book.find_by_slug("anti-oedipus")
|
19
|
+
#<Book _id: 4c23b1f7faa4a7479a000009, slug: "anti-oedipus", title: "Anti Oedipus">
|
data/lib/mongoid_slug.rb
CHANGED
@@ -7,14 +7,18 @@ module Mongoid::Slug
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods #:nodoc:
|
10
|
-
|
10
|
+
|
11
11
|
# Set a field as source of slug
|
12
|
-
def slug(field)
|
13
|
-
class_variable_set(:@@
|
12
|
+
def slug(*field)
|
13
|
+
class_variable_set(:@@slugged_fields, field)
|
14
14
|
end
|
15
15
|
|
16
16
|
def find_by_slug(slug)
|
17
|
-
|
17
|
+
if embedded?
|
18
|
+
raise 'I have not implemented this method yet for embedded docs. Try: parent.children.where(:slug => "foo") instead'
|
19
|
+
else
|
20
|
+
where(:slug => slug).first
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
@@ -25,12 +29,18 @@ module Mongoid::Slug
|
|
25
29
|
private
|
26
30
|
|
27
31
|
def slugify
|
28
|
-
self.slug = find_unique_slug if new_record? ||
|
32
|
+
self.slug = find_unique_slug if new_record? || slugged_fields_changed?
|
33
|
+
end
|
34
|
+
|
35
|
+
def slugged_fields_changed?
|
36
|
+
self.class.class_eval('@@slugged_fields').any? do |field|
|
37
|
+
self.send(field.to_s + '_changed?')
|
38
|
+
end
|
29
39
|
end
|
30
40
|
|
31
41
|
def find_unique_slug(suffix='')
|
32
|
-
slug = ("#{
|
33
|
-
if collection.find(:slug => slug).count == 0
|
42
|
+
slug = ("#{slug_base} #{suffix}").parameterize
|
43
|
+
if (embedded? ? self._parent.collection.find("#{self.class.to_s.downcase.pluralize}.slug" => slug) : collection.find(:slug => slug)).count == 0
|
34
44
|
slug
|
35
45
|
else
|
36
46
|
new_suffix = suffix.blank? ? '1' : "#{suffix.to_i + 1}"
|
@@ -38,7 +48,7 @@ module Mongoid::Slug
|
|
38
48
|
end
|
39
49
|
end
|
40
50
|
|
41
|
-
def
|
42
|
-
self.
|
51
|
+
def slug_base
|
52
|
+
self.class.class_eval('@@slugged_fields').collect{ |field| self.send(field) }.join(" ")
|
43
53
|
end
|
44
54
|
end
|
data/spec/models/book.rb
CHANGED
@@ -1,40 +1,154 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Mongoid::Slug do
|
4
|
+
|
4
5
|
before(:each) do
|
5
|
-
@book =
|
6
|
+
@book = Book.create(:title => "A Thousand Plateaus", :isbn => "9789245242475")
|
6
7
|
end
|
7
8
|
|
8
|
-
|
9
|
-
@book.to_param.should eql @book.title.parameterize
|
10
|
-
end
|
9
|
+
context "root" do
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
11
|
+
it "generates slug" do
|
12
|
+
@book.to_param.should eql @book.title.parameterize
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
it "updates slug" do
|
16
|
+
@book.update_attributes(:title => "Anti Oedipus")
|
17
|
+
@book.to_param.should eql "Anti Oedipus".parameterize
|
18
|
+
end
|
19
|
+
|
20
|
+
it "generates a unique slug" do
|
21
|
+
similar_book = Book.create(:title => @book.title)
|
22
|
+
similar_book.to_param.should_not eql @book.to_param
|
23
|
+
end
|
24
|
+
|
25
|
+
it "appends a counter when slug is not unique" do
|
26
|
+
similar_book = Book.create(:title => @book.title)
|
27
|
+
similar_book.slug.should match /\d$/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "does not append a counter when slug is unique" do
|
31
|
+
@book.slug.should_not match /\d$/
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does not update slug if slugged field has not changed" do
|
35
|
+
existing_slug = @book.slug
|
36
|
+
@book.update_attributes('isbn' => "9785545858118")
|
37
|
+
@book.slug.should eql existing_slug
|
38
|
+
end
|
39
|
+
|
40
|
+
context ".find_by_slug" do
|
41
|
+
it "finds by slug" do
|
42
|
+
Book.find_by_slug(@book.slug).should eql @book
|
43
|
+
end
|
44
|
+
end
|
21
45
|
|
22
|
-
it "appends a counter when slug is not unique" do
|
23
|
-
similar_book = Book.create(:title => @book.title)
|
24
|
-
similar_book.slug.should match /\d$/
|
25
46
|
end
|
26
47
|
|
27
|
-
|
28
|
-
|
48
|
+
context "embedded has many" do
|
49
|
+
|
50
|
+
before(:each) do
|
51
|
+
@subject = @book.subjects.create(:name => "Psychoanalysis")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "generates slug" do
|
55
|
+
@subject.to_param.should eql(@subject.name.parameterize)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "updates slug" do
|
59
|
+
@subject.update_attributes(:name => "Schizoanalysis")
|
60
|
+
@subject.to_param.should eql "Schizoanalysis".parameterize
|
61
|
+
end
|
62
|
+
|
63
|
+
it "generates a unique slug" do
|
64
|
+
similar_subject = @book.subjects.create(:model => @subject.name)
|
65
|
+
similar_subject.to_param.should_not eql @subject.to_param
|
66
|
+
end
|
67
|
+
|
68
|
+
it "appends a counter when slug is not unique" do
|
69
|
+
similar_subject = @book.subjects.create(:name => @subject.name)
|
70
|
+
similar_subject.slug.should match /\d$/
|
71
|
+
end
|
72
|
+
|
73
|
+
it "does not append a counter when slug is unique" do
|
74
|
+
@subject.slug.should_not match /\d$/
|
75
|
+
end
|
76
|
+
|
77
|
+
it "does not update slug if slugged field has not changed" do
|
78
|
+
existing_slug = @subject.slug
|
79
|
+
@subject.update_attributes(:description => "Lorem ipsum dolor sit amet")
|
80
|
+
@subject.slug.should eql existing_slug
|
81
|
+
end
|
82
|
+
|
83
|
+
context ".find_by_slug" do
|
84
|
+
it "raises error" do
|
85
|
+
lambda { @book.subjects.find_by_slug(@subject.slug) }.should raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
it "does find by a regular where" do
|
89
|
+
@book.subjects.where(:slug => @subject.slug).first.should eql @subject
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
29
93
|
end
|
30
94
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
95
|
+
context "embedded has one" do
|
96
|
+
|
97
|
+
before(:each) do
|
98
|
+
@publisher = @book.create_publisher(:name => "OUP")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "generates slug" do
|
102
|
+
@publisher.to_param.should eql(@publisher.name.parameterize)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "updates slug" do
|
106
|
+
@publisher.update_attributes(:name => "Harvard UP")
|
107
|
+
@publisher.to_param.should eql "Harvard UP".parameterize
|
108
|
+
end
|
109
|
+
|
110
|
+
it "does not update slug if slugged field has not changed" do
|
111
|
+
existing_slug = @publisher.slug
|
112
|
+
@publisher.update_attributes(:year => 2001)
|
113
|
+
@publisher.slug.should eql existing_slug
|
114
|
+
end
|
115
|
+
|
35
116
|
end
|
36
117
|
|
37
|
-
|
38
|
-
|
118
|
+
context "slugging composite fields" do
|
119
|
+
before(:each) do
|
120
|
+
@author = Author.create(:first_name => "Gilles", :last_name => "Deleuze")
|
121
|
+
end
|
122
|
+
|
123
|
+
it "generates slug" do
|
124
|
+
@author.to_param.should eql("Gilles Deleuze".parameterize)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "updates slug" do
|
128
|
+
@author.update_attributes(:first_name => "Félix", :last_name => "Guattari")
|
129
|
+
@author.to_param.should eql "Félix Guattari".parameterize
|
130
|
+
end
|
131
|
+
|
132
|
+
it "generates a unique slug" do
|
133
|
+
similar_author = Author.create(:first_name => @author.first_name,
|
134
|
+
:last_name => @author.last_name)
|
135
|
+
similar_author.to_param.should_not eql @author.to_param
|
136
|
+
end
|
137
|
+
|
138
|
+
it "appends a counter when slug is not unique" do
|
139
|
+
similar_author = Author.create(:first_name => @author.first_name,
|
140
|
+
:last_name => @author.last_name)
|
141
|
+
similar_author.slug.should match /\d$/
|
142
|
+
end
|
143
|
+
|
144
|
+
it "does not append a counter when slug is unique" do
|
145
|
+
@author.slug.should_not match /\d$/
|
146
|
+
end
|
147
|
+
|
148
|
+
context ".find_by_slug" do
|
149
|
+
it "finds by slug" do
|
150
|
+
Author.find_by_slug("gilles-deleuze").should eql @author
|
151
|
+
end
|
152
|
+
end
|
39
153
|
end
|
40
154
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_slug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Hakan Ensari
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-24 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -48,7 +48,10 @@ files:
|
|
48
48
|
- LICENSE
|
49
49
|
- README.rdoc
|
50
50
|
- lib/mongoid_slug.rb
|
51
|
+
- spec/models/author.rb
|
51
52
|
- spec/models/book.rb
|
53
|
+
- spec/models/publisher.rb
|
54
|
+
- spec/models/subject.rb
|
52
55
|
- spec/spec_helper.rb
|
53
56
|
- spec/unit/mongoid_slug_spec.rb
|
54
57
|
has_rdoc: true
|
@@ -86,6 +89,9 @@ signing_key:
|
|
86
89
|
specification_version: 3
|
87
90
|
summary: Generates a URL slug in a Mongoid model
|
88
91
|
test_files:
|
92
|
+
- spec/models/author.rb
|
89
93
|
- spec/models/book.rb
|
94
|
+
- spec/models/publisher.rb
|
95
|
+
- spec/models/subject.rb
|
90
96
|
- spec/spec_helper.rb
|
91
97
|
- spec/unit/mongoid_slug_spec.rb
|