mongoid_slug 0.4.6 → 0.4.7

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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Hakan Ensari
1
+ Copyright (c) 2010 Paper Cavalier
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -3,8 +3,15 @@ Mongoid Slug
3
3
 
4
4
  Mongoid Slug generates a URL slug or permalink based on a field or set of fields in a Mongoid model.
5
5
 
6
- Examples
7
- --------
6
+ Install
7
+ -------
8
+
9
+ To install mongoid_slug, add it to your Gemfile:
10
+
11
+ gem 'mongoid_slug', :require => 'mongoid/slug'
12
+
13
+ Usage
14
+ -----
8
15
 
9
16
  Here's a book that embeds many authors:
10
17
 
@@ -57,4 +64,4 @@ To demo some more functionality in the console:
57
64
  >> book.authors.where(:slug => 'felix-guattari).first
58
65
  => #<Author _id: 4c31e362faa4a7050e000003, slug: "félix-guattari", last_name: "Guattari", first_name: "Félix">
59
66
 
60
- `slug` takes `:as` and `:scoped` as arguments. See models in specs for more examples.
67
+ See [sample models in specs]("http://github.com/papercavalier/mongoid-slug/tree/master/spec/models/") for various configuration options.
@@ -0,0 +1,5 @@
1
+ module Mongoid #:nodoc:
2
+ module Slug
3
+ VERSION = "0.4.7"
4
+ end
5
+ end
@@ -0,0 +1,93 @@
1
+ #encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+
4
+ # Generates a URL slug/permalink based on fields in a Mongoid model
5
+ module Slug
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ cattr_accessor :slug_name, :slugged_fields, :slug_scoped
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Set a field or a number of fields as source of slug
15
+ def slug(*args)
16
+ options = args.last.is_a?(Hash) ? args.pop : {}
17
+
18
+ self.slug_name = options[:as] || :slug
19
+ self.slug_scoped = options[:scoped] || false
20
+ self.slugged_fields = args
21
+
22
+ field slug_name
23
+
24
+ if slug_scoped
25
+ index slug_name
26
+ else
27
+ index slug_name, :unique => true
28
+ end
29
+
30
+ if options[:permanent]
31
+ before_create :generate_slug
32
+ else
33
+ before_save :generate_slug
34
+ end
35
+ end
36
+ end
37
+
38
+ def to_param
39
+ self.send slug_name
40
+ end
41
+
42
+ private
43
+
44
+ def find_(slug, stack=[])
45
+ if embedded?
46
+ if slug_scoped && stack.empty?
47
+ _parent.send(association_name).where( slug_name => slug ).to_a
48
+ else
49
+ stack << association_name
50
+ _parent.send :find_, slug, stack
51
+ end
52
+ else
53
+ stack.reverse!
54
+ path = (stack + [slug_name]).join(".")
55
+ found = collection.find(path => slug).to_a
56
+
57
+ stack.each do |name|
58
+ if found.any?
59
+ found = found.first.send(name).to_a
60
+ end
61
+ end
62
+
63
+ found
64
+ end
65
+ end
66
+
67
+ def find_unique_slug(suffix='')
68
+ slug = ("#{slug_base} #{suffix}").parameterize
69
+ if find_(slug).reject{ |doc| doc.id == self.id }.empty?
70
+ slug
71
+ else
72
+ suffix = suffix.blank? ? '1' : "#{suffix.to_i + 1}"
73
+ find_unique_slug(suffix)
74
+ end
75
+ end
76
+
77
+ def generate_slug
78
+ if new_record? || slugged_fields_changed?
79
+ self.send("#{slug_name}=", find_unique_slug)
80
+ end
81
+ end
82
+
83
+ def slug_base
84
+ self.class.slugged_fields.collect{ |field| self.send(field) }.join(" ")
85
+ end
86
+
87
+ def slugged_fields_changed?
88
+ self.class.slugged_fields.any? do |field|
89
+ self.send(field.to_s + '_changed?')
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,6 @@
1
+ class Permanent
2
+ include Mongoid::Document
3
+ include Mongoid::Slug
4
+ field :title
5
+ slug :title, :permanent => true
6
+ end
@@ -0,0 +1,318 @@
1
+ #encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ module Mongoid
5
+
6
+ describe Slug do
7
+
8
+ let(:book) { Book.create(:title => "A Thousand Plateaus", :isbn => "9789245242475") }
9
+
10
+ context "when document is root" do
11
+
12
+ it "generates slug" do
13
+ book.to_param.should eql book.title.parameterize
14
+ end
15
+
16
+ it "updates slug" do
17
+ book.update_attributes(:title => "Anti Oedipus")
18
+ book.to_param.should eql "Anti Oedipus".parameterize
19
+ end
20
+
21
+ it "generates a unique slug" do
22
+ similar_book = Book.create(:title => book.title)
23
+ similar_book.to_param.should_not eql book.to_param
24
+ end
25
+
26
+ it "appends a counter when slug is not unique" do
27
+ similar_book = Book.create(:title => book.title)
28
+ similar_book.to_param.should match /\d$/
29
+ end
30
+
31
+ it "does not append a counter when slug is unique" do
32
+ book.to_param.should_not match /\d$/
33
+ end
34
+
35
+ it "does not update slug if slugged fields have not changed" do
36
+ former_slug = book.to_param
37
+ book.update_attributes(:isbn => "9785545858118")
38
+ book.to_param.should eql former_slug
39
+ end
40
+
41
+ it "does not update slug if slugged fields have changed but generated slug is the same" do
42
+ former_slug = book.to_param
43
+ book.update_attributes(:title => "A thousand plateaus")
44
+ book.to_param.should eql former_slug
45
+ end
46
+
47
+ it "finds by slug" do
48
+ Book.where(:slug => book.to_param).first.should eql book
49
+ end
50
+
51
+ end
52
+
53
+ context "when document is an embedded has-many" do
54
+
55
+ let(:subject) { book.subjects.create(:name => "Psychoanalysis") }
56
+
57
+ it "generates slug" do
58
+ subject.to_param.should eql(subject.name.parameterize)
59
+ end
60
+
61
+ it "updates slug" do
62
+ subject.update_attributes(:name => "Schizoanalysis")
63
+ subject.to_param.should eql "Schizoanalysis".parameterize
64
+ end
65
+
66
+ it "generates a unique slug" do
67
+ similar_subject = book.subjects.create(:model => subject.name)
68
+ similar_subject.to_param.should_not eql subject.to_param
69
+ end
70
+
71
+ it "appends a counter when slug is not unique" do
72
+ similar_subject = book.subjects.create(:name => subject.name)
73
+ similar_subject.to_param.should match /\d$/
74
+ end
75
+
76
+ it "does not append a counter when slug is unique" do
77
+ subject.to_param.should_not match /\d$/
78
+ end
79
+
80
+ it "does not update slug if slugged fields have not changed" do
81
+ former_slug = subject.to_param
82
+ subject.update_attributes(:description => "Lorem ipsum dolor sit amet")
83
+ subject.to_param.should eql former_slug
84
+ end
85
+
86
+ it "does not update slug if slugged fields have changed but generated slug is the same" do
87
+ former_slug = subject.to_param
88
+ subject.update_attributes(:title => "PSYCHOANALYSIS")
89
+ subject.to_param.should eql former_slug
90
+ end
91
+
92
+ it "finds by slug" do
93
+ book.subjects.where(:slug => subject.to_param).first.should eql subject
94
+ end
95
+
96
+ end
97
+
98
+ context "when document is an embedded has-one" do
99
+
100
+ let(:publisher) { book.create_publisher(:name => "OUP") }
101
+
102
+ it "generates slug" do
103
+ publisher.to_param.should eql(publisher.name.parameterize)
104
+ end
105
+
106
+ it "updates slug" do
107
+ publisher.update_attributes(:name => "Harvard UP")
108
+ publisher.to_param.should eql "Harvard UP".parameterize
109
+ end
110
+
111
+ it "does not update slug if slugged fields have not changed" do
112
+ former_slug = publisher.to_param
113
+ publisher.update_attributes(:year => 2001)
114
+ publisher.to_param.should eql former_slug
115
+ end
116
+
117
+ it "does not update slug if slugged fields have changed but generated slug is the same" do
118
+ former_slug = publisher.to_param
119
+ publisher.update_attributes(:name => "oup")
120
+ publisher.to_param.should eql former_slug
121
+ end
122
+
123
+ end
124
+
125
+ context "when the slug is composed of multiple fields" do
126
+
127
+ let(:author) { Author.create(:first_name => "Gilles", :last_name => "Deleuze") }
128
+
129
+ it "generates slug" do
130
+ author.to_param.should eql("Gilles Deleuze".parameterize)
131
+ end
132
+
133
+ it "updates slug" do
134
+ author.update_attributes(:first_name => "Félix", :last_name => "Guattari")
135
+ author.to_param.should eql "Félix Guattari".parameterize
136
+ end
137
+
138
+ it "generates a unique slug" do
139
+ similar_author = Author.create(:first_name => author.first_name,
140
+ :last_name => author.last_name)
141
+ similar_author.to_param.should_not eql author.to_param
142
+ end
143
+
144
+ it "appends a counter when slug is not unique" do
145
+ similar_author = Author.create(:first_name => author.first_name,
146
+ :last_name => author.last_name)
147
+ similar_author.to_param.should match /\d$/
148
+ end
149
+
150
+ it "does not append a counter when slug is unique" do
151
+ author.to_param.should_not match /\d$/
152
+ end
153
+
154
+ it "does not update slug if slugged fields have changed but generated slug is the same" do
155
+ former_slug = author.to_param
156
+ author.update_attributes(:first_name => "gilles", :last_name => "DELEUZE")
157
+ author.to_param.should eql former_slug
158
+ end
159
+
160
+ it "finds by slug" do
161
+ author
162
+ Author.where(:slug => "gilles-deleuze").first.should eql author
163
+ end
164
+
165
+ end
166
+
167
+ context "when the document is embedded in another embedded document" do
168
+
169
+ let(:foo) { Foo.create(:name => "foo") }
170
+ let(:bar) { foo.bars.create(:name => "bar") }
171
+ let(:baz) do
172
+ bar.bazes.create(:name => "baz")
173
+ Foo.first.bars.first.bazes.first # Better to be paranoid and reload from db
174
+ end
175
+
176
+ it "generates slug" do
177
+ baz.to_param.should eql(baz.name.parameterize)
178
+ end
179
+
180
+ it "updates slug" do
181
+ baz.update_attributes(:name => "lorem")
182
+ baz.to_param.should eql "lorem".parameterize
183
+ end
184
+
185
+ it "generates a unique slug" do
186
+ similar_baz = bar.bazes.create(:name => baz.name)
187
+ similar_baz.to_param.should_not eql baz.to_param
188
+ end
189
+
190
+ it "appends a counter when slug is not unique" do
191
+ similar_baz = bar.bazes.create(:name => baz.name)
192
+ similar_baz.to_param.should match /\d$/
193
+ end
194
+
195
+ it "does not append a counter when slug is unique" do
196
+ baz.to_param.should_not match /\d$/
197
+ end
198
+
199
+ it "does not update slug if slugged fields have not changed" do
200
+ former_slug = baz.to_param
201
+ baz.update_attributes(:other => "Lorem ipsum dolor sit amet")
202
+ baz.to_param.should eql former_slug
203
+ end
204
+
205
+ it "does not update slug if slugged fields have changed but generated slug is the same" do
206
+ former_slug = baz.to_param
207
+ baz.update_attributes(:name => "BAZ")
208
+ baz.to_param.should eql former_slug
209
+ end
210
+
211
+ it "finds by slug" do
212
+ bar.bazes.where(:slug => baz.to_param).first.should eql baz
213
+ end
214
+
215
+ end
216
+
217
+ context "when the slug field name is customized" do
218
+
219
+ let(:person) { Person.create(:name => "John Doe") }
220
+
221
+ it "sets the slug field name" do
222
+ person.respond_to?(:permalink).should be_true
223
+ person.send(:permalink).should eql "john-doe"
224
+ end
225
+
226
+ it "generates slug" do
227
+ person.to_param.should eql(person.name.parameterize)
228
+ end
229
+
230
+ it "updates slug" do
231
+ person.update_attributes(:name => "Jane Doe")
232
+ person.to_param.should eql "Jane Doe".parameterize
233
+ end
234
+
235
+ it "generates a unique slug" do
236
+ similar_person = Person.create(:name => person.name)
237
+ similar_person.to_param.should_not eql person.to_param
238
+ end
239
+
240
+ it "appends a counter when slug is not unique" do
241
+ similar_person = Person.create(:name => person.name)
242
+ similar_person.to_param.should match /\d$/
243
+ end
244
+
245
+ it "does not append a counter when slug is unique" do
246
+ person.to_param.should_not match /\d$/
247
+ end
248
+
249
+ it "does not update slug if slugged fields have not changed" do
250
+ former_slug = person.to_param
251
+ person.update_attributes(:age => 31)
252
+ person.to_param.should eql former_slug
253
+ end
254
+
255
+ it "does not update slug if slugged fields have changed but generated slug is the same" do
256
+ former_slug = person.to_param
257
+ person.update_attributes(:name => "JOHN DOE")
258
+ person.to_param.should eql former_slug
259
+ end
260
+
261
+ it "finds by slug" do
262
+ Person.where(:permalink => person.to_param).first.should eql person
263
+ end
264
+
265
+ end
266
+
267
+ describe "#find_" do
268
+
269
+ let(:foo) { Foo.create(:name => "foo") }
270
+ let(:bar) { foo.bars.create(:name => "bar") }
271
+ let(:baz) { bar.bazes.create(:name => "baz") }
272
+
273
+ it "finds duplicate slug of a root document" do
274
+ foo.send(:find_, foo.to_param).count.should eql 1
275
+ end
276
+
277
+ it "finds duplicate slug of an embedded document" do
278
+ bar.send(:find_, bar.to_param).count.should eql 1
279
+ end
280
+
281
+ it "finds duplicate slug of a deeply-embedded document" do
282
+ baz.send(:find_, baz.to_param).count.should eql 1
283
+ end
284
+
285
+ end
286
+
287
+ context "when slug is scoped" do
288
+
289
+ let(:foo) { Foo.create(:name => "foo") }
290
+ let(:sar) { foo.sars.create(:name => "sar") }
291
+ let(:foo2) { Foo.create(:name => "foo") }
292
+
293
+ it "generates a unique slug inside the same parent object" do
294
+ similar_sar = foo.sars.create(:name => sar.name)
295
+ similar_sar.to_param.should_not eql sar.to_param
296
+ end
297
+
298
+ it "generates the same slug in different parent object" do
299
+ other_sar = foo2.sars.create(:name => sar.name)
300
+ other_sar.to_param.should eql sar.to_param
301
+ end
302
+
303
+ end
304
+
305
+ context "when slug is permanent" do
306
+
307
+ let(:permanent) { Permanent.create(:title => "This is a nodding song") }
308
+
309
+ it "doesn't change slug when document is updated" do
310
+ permanent.update_attributes(:title => "This is not a nodding song")
311
+ permanent.to_param.should eql "This is a nodding song".parameterize
312
+ end
313
+
314
+ end
315
+
316
+ end
317
+
318
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,30 +1,21 @@
1
1
  require "rubygems"
2
2
  require "bundler/setup"
3
3
 
4
- require "rspec"
5
4
  require "database_cleaner"
6
5
  require "mongoid"
6
+ require "rspec"
7
7
 
8
8
  Mongoid.configure do |config|
9
9
  name = "mongoid_slug_test"
10
10
  config.master = Mongo::Connection.new.db(name)
11
11
  end
12
12
 
13
- require File.expand_path("../../lib/mongoid_slug", __FILE__)
14
- Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |f| require f }
15
-
16
- DatabaseCleaner.orm = "mongoid"
17
-
18
- Rspec.configure do |config|
19
- config.before(:all) do
20
- DatabaseCleaner.strategy = :truncation
21
- end
13
+ require File.expand_path("../../lib/mongoid/slug", __FILE__)
22
14
 
23
- config.before(:each) do
24
- DatabaseCleaner.start
25
- end
15
+ Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |f| require f }
26
16
 
27
- config.after(:each) do
28
- DatabaseCleaner.clean
29
- end
17
+ Rspec.configure do |c|
18
+ c.before(:all) { DatabaseCleaner.strategy = :truncation }
19
+ c.before(:each) { DatabaseCleaner.start }
20
+ c.after(:each) { DatabaseCleaner.clean }
30
21
  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: 3
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 6
10
- version: 0.4.6
9
+ - 7
10
+ version: 0.4.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Hakan Ensari
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-08-11 00:00:00 +01:00
19
+ date: 2010-10-31 01:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -27,46 +27,97 @@ dependencies:
27
27
  requirements:
28
28
  - - ~>
29
29
  - !ruby/object:Gem::Version
30
- hash: 31098209
30
+ hash: 62196421
31
31
  segments:
32
32
  - 2
33
33
  - 0
34
34
  - 0
35
35
  - beta
36
- version: 2.0.0.beta
36
+ - 19
37
+ version: 2.0.0.beta.19
37
38
  type: :runtime
38
39
  version_requirements: *id001
39
- description: Mongoid Slug generates a URL slug/permalink based on fields in a Mongoid model.
40
- email: code@papercavalier.com
40
+ - !ruby/object:Gem::Dependency
41
+ name: bson_ext
42
+ prerelease: false
43
+ requirement: &id002 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ hash: 17
49
+ segments:
50
+ - 1
51
+ - 1
52
+ - 1
53
+ version: 1.1.1
54
+ type: :development
55
+ version_requirements: *id002
56
+ - !ruby/object:Gem::Dependency
57
+ name: database_cleaner
58
+ prerelease: false
59
+ requirement: &id003 !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ~>
63
+ - !ruby/object:Gem::Version
64
+ hash: 7
65
+ segments:
66
+ - 0
67
+ - 6
68
+ - 0
69
+ version: 0.6.0
70
+ type: :development
71
+ version_requirements: *id003
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec
74
+ prerelease: false
75
+ requirement: &id004 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ~>
79
+ - !ruby/object:Gem::Version
80
+ hash: 13
81
+ segments:
82
+ - 2
83
+ - 0
84
+ - 1
85
+ version: 2.0.1
86
+ type: :development
87
+ version_requirements: *id004
88
+ description: Generates a URL slug or permalink based on fields in a Mongoid model.
89
+ email:
90
+ - code@papercavalier.com
41
91
  executables: []
42
92
 
43
93
  extensions: []
44
94
 
45
- extra_rdoc_files:
46
- - LICENSE
47
- - README.md
95
+ extra_rdoc_files: []
96
+
48
97
  files:
98
+ - lib/mongoid/slug/version.rb
99
+ - lib/mongoid/slug.rb
49
100
  - LICENSE
50
- - lib/mongoid_slug.rb
51
101
  - README.md
52
102
  - spec/models/author.rb
53
103
  - spec/models/bar.rb
54
104
  - spec/models/baz.rb
55
105
  - spec/models/book.rb
56
106
  - spec/models/foo.rb
107
+ - spec/models/permanent.rb
57
108
  - spec/models/person.rb
58
109
  - spec/models/publisher.rb
59
110
  - spec/models/sar.rb
60
111
  - spec/models/subject.rb
61
- - spec/mongoid_slug_spec.rb
112
+ - spec/mongoid/slug_spec.rb
62
113
  - spec/spec_helper.rb
63
114
  has_rdoc: true
64
- homepage: http://github.com/papercavalier/mongoid-slug
115
+ homepage: http://github.com/papercavalier/mongoid_slug
65
116
  licenses: []
66
117
 
67
118
  post_install_message:
68
- rdoc_options:
69
- - --charset=UTF-8
119
+ rdoc_options: []
120
+
70
121
  require_paths:
71
122
  - lib
72
123
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -89,20 +140,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
140
  version: "0"
90
141
  requirements: []
91
142
 
92
- rubyforge_project:
143
+ rubyforge_project: mongoid_slug
93
144
  rubygems_version: 1.3.7
94
145
  signing_key:
95
146
  specification_version: 3
96
- summary: Generates a URL slug in a Mongoid model
147
+ summary: Generates a URL slug or permalink
97
148
  test_files:
98
149
  - spec/models/author.rb
99
150
  - spec/models/bar.rb
100
151
  - spec/models/baz.rb
101
152
  - spec/models/book.rb
102
153
  - spec/models/foo.rb
154
+ - spec/models/permanent.rb
103
155
  - spec/models/person.rb
104
156
  - spec/models/publisher.rb
105
157
  - spec/models/sar.rb
106
158
  - spec/models/subject.rb
107
- - spec/mongoid_slug_spec.rb
159
+ - spec/mongoid/slug_spec.rb
108
160
  - spec/spec_helper.rb
data/lib/mongoid_slug.rb DELETED
@@ -1,81 +0,0 @@
1
- # Generates a URL slug/permalink based on fields in a Mongoid model.
2
- module Mongoid::Slug
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- cattr_accessor :slug_name, :slugged_fields, :slug_scoped
7
- end
8
-
9
- module ClassMethods #:nodoc:
10
- # Set a field or a number of fields as source of slug
11
- def slug(*args)
12
- options = args.last.is_a?(Hash) ? args.pop : {}
13
- self.slug_name = options[:as] || :slug
14
- self.slug_scoped = options[:scoped] || false
15
- self.slugged_fields = args
16
-
17
- field slug_name
18
- if slug_scoped
19
- index slug_name
20
- else
21
- index slug_name, :unique => true
22
- end
23
- before_save :generate_slug
24
- end
25
- end
26
-
27
- def to_param
28
- self.send slug_name
29
- end
30
-
31
- private
32
-
33
- def find_(slug, stack=[])
34
- if embedded?
35
- if slug_scoped && stack.empty?
36
- _parent.send(association_name).where( slug_name => slug ).to_a
37
- else
38
- stack << association_name
39
- _parent.send :find_, slug, stack
40
- end
41
- else
42
- stack.reverse!
43
- path = (stack + [slug_name]).join(".")
44
- found = collection.find(path => slug).to_a
45
-
46
- stack.each do |name|
47
- if found.any?
48
- found = found.first.send(name).to_a
49
- end
50
- end
51
-
52
- found
53
- end
54
- end
55
-
56
- def find_unique_slug(suffix='')
57
- slug = ("#{slug_base} #{suffix}").parameterize
58
- if find_(slug).reject{ |doc| doc.id == self.id }.empty?
59
- slug
60
- else
61
- suffix = suffix.blank? ? '1' : "#{suffix.to_i + 1}"
62
- find_unique_slug(suffix)
63
- end
64
- end
65
-
66
- def generate_slug
67
- if new_record? || slugged_fields_changed?
68
- self.send("#{slug_name}=", find_unique_slug)
69
- end
70
- end
71
-
72
- def slug_base
73
- self.class.slugged_fields.collect{ |field| self.send(field) }.join(" ")
74
- end
75
-
76
- def slugged_fields_changed?
77
- self.class.slugged_fields.any? do |field|
78
- self.send(field.to_s + '_changed?')
79
- end
80
- end
81
- end
@@ -1,314 +0,0 @@
1
- #encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Mongoid::Slug do
6
-
7
- before(:each) do
8
- @book = Book.create(:title => "A Thousand Plateaus", :isbn => "9789245242475")
9
- end
10
-
11
- context "root document" do
12
-
13
- it "generates slug" do
14
- @book.to_param.should eql @book.title.parameterize
15
- end
16
-
17
- it "updates slug" do
18
- @book.update_attributes(:title => "Anti Oedipus")
19
- @book.to_param.should eql "Anti Oedipus".parameterize
20
- end
21
-
22
- it "generates a unique slug" do
23
- similar_book = Book.create(:title => @book.title)
24
- similar_book.to_param.should_not eql @book.to_param
25
- end
26
-
27
- it "appends a counter when slug is not unique" do
28
- similar_book = Book.create(:title => @book.title)
29
- similar_book.to_param.should match /\d$/
30
- end
31
-
32
- it "does not append a counter when slug is unique" do
33
- @book.to_param.should_not match /\d$/
34
- end
35
-
36
- it "does not update slug if slugged fields have not changed" do
37
- former_slug = @book.to_param
38
- @book.update_attributes(:isbn => "9785545858118")
39
- @book.to_param.should eql former_slug
40
- end
41
-
42
- it "does not update slug if slugged fields have changed but generated slug is the same" do
43
- former_slug = @book.to_param
44
- @book.update_attributes(:title => "A thousand plateaus")
45
- @book.to_param.should eql former_slug
46
- end
47
-
48
- it "finds by slug" do
49
- Book.where(:slug => @book.to_param).first.should eql @book
50
- end
51
-
52
- end
53
-
54
- context "embedded has many" do
55
-
56
- before(:each) do
57
- @subject = @book.subjects.create(:name => "Psychoanalysis")
58
- end
59
-
60
- it "generates slug" do
61
- @subject.to_param.should eql(@subject.name.parameterize)
62
- end
63
-
64
- it "updates slug" do
65
- @subject.update_attributes(:name => "Schizoanalysis")
66
- @subject.to_param.should eql "Schizoanalysis".parameterize
67
- end
68
-
69
- it "generates a unique slug" do
70
- similar_subject = @book.subjects.create(:model => @subject.name)
71
- similar_subject.to_param.should_not eql @subject.to_param
72
- end
73
-
74
- it "appends a counter when slug is not unique" do
75
- similar_subject = @book.subjects.create(:name => @subject.name)
76
- similar_subject.to_param.should match /\d$/
77
- end
78
-
79
- it "does not append a counter when slug is unique" do
80
- @subject.to_param.should_not match /\d$/
81
- end
82
-
83
- it "does not update slug if slugged fields have not changed" do
84
- former_slug = @subject.to_param
85
- @subject.update_attributes(:description => "Lorem ipsum dolor sit amet")
86
- @subject.to_param.should eql former_slug
87
- end
88
-
89
- it "does not update slug if slugged fields have changed but generated slug is the same" do
90
- former_slug = @subject.to_param
91
- @subject.update_attributes(:title => "PSYCHOANALYSIS")
92
- @subject.to_param.should eql former_slug
93
- end
94
-
95
- it "finds by slug" do
96
- @book.subjects.where(:slug => @subject.to_param).first.should eql @subject
97
- end
98
-
99
- end
100
-
101
- context "embedded has one" do
102
-
103
- before(:each) do
104
- @publisher = @book.create_publisher(:name => "OUP")
105
- end
106
-
107
- it "generates slug" do
108
- @publisher.to_param.should eql(@publisher.name.parameterize)
109
- end
110
-
111
- it "updates slug" do
112
- @publisher.update_attributes(:name => "Harvard UP")
113
- @publisher.to_param.should eql "Harvard UP".parameterize
114
- end
115
-
116
- it "does not update slug if slugged fields have not changed" do
117
- former_slug = @publisher.to_param
118
- @publisher.update_attributes(:year => 2001)
119
- @publisher.to_param.should eql former_slug
120
- end
121
-
122
- it "does not update slug if slugged fields have changed but generated slug is the same" do
123
- former_slug = @publisher.to_param
124
- @publisher.update_attributes(:name => "oup")
125
- @publisher.to_param.should eql former_slug
126
- end
127
-
128
- end
129
-
130
- context "composite fields" do
131
- before(:each) do
132
- @author = Author.create(:first_name => "Gilles", :last_name => "Deleuze")
133
- end
134
-
135
- it "generates slug" do
136
- @author.to_param.should eql("Gilles Deleuze".parameterize)
137
- end
138
-
139
- it "updates slug" do
140
- @author.update_attributes(:first_name => "Félix", :last_name => "Guattari")
141
- @author.to_param.should eql "Félix Guattari".parameterize
142
- end
143
-
144
- it "generates a unique slug" do
145
- similar_author = Author.create(:first_name => @author.first_name,
146
- :last_name => @author.last_name)
147
- similar_author.to_param.should_not eql @author.to_param
148
- end
149
-
150
- it "appends a counter when slug is not unique" do
151
- similar_author = Author.create(:first_name => @author.first_name,
152
- :last_name => @author.last_name)
153
- similar_author.to_param.should match /\d$/
154
- end
155
-
156
- it "does not append a counter when slug is unique" do
157
- @author.to_param.should_not match /\d$/
158
- end
159
-
160
- it "does not update slug if slugged fields have changed but generated slug is the same" do
161
- former_slug = @author.to_param
162
- @author.update_attributes(:first_name => "gilles", :last_name => "DELEUZE")
163
- @author.to_param.should eql former_slug
164
- end
165
-
166
- it "finds by slug" do
167
- Author.where(:slug => "gilles-deleuze").first.should eql @author
168
- end
169
-
170
- end
171
-
172
- context "deeply embedded relationships" do
173
-
174
- before(:each) do
175
- @foo = Foo.create(:name => "foo")
176
- @bar = @foo.bars.create(:name => "bar")
177
- @baz = @bar.bazes.create(:name => "baz")
178
- @baz = Foo.first.bars.first.bazes.first # Better to be paranoid and reload from db
179
- end
180
-
181
- it "generates slug" do
182
- @baz.to_param.should eql(@baz.name.parameterize)
183
- end
184
-
185
- it "updates slug" do
186
- @baz.update_attributes(:name => "lorem")
187
- @baz.to_param.should eql "lorem".parameterize
188
- end
189
-
190
- it "generates a unique slug" do
191
- similar_baz = @bar.bazes.create(:name => @baz.name)
192
- similar_baz.to_param.should_not eql @baz.to_param
193
- end
194
-
195
- it "appends a counter when slug is not unique" do
196
- similar_baz = @bar.bazes.create(:name => @baz.name)
197
- similar_baz.to_param.should match /\d$/
198
- end
199
-
200
- it "does not append a counter when slug is unique" do
201
- @baz.to_param.should_not match /\d$/
202
- end
203
-
204
- it "does not update slug if slugged fields have not changed" do
205
- former_slug = @baz.to_param
206
- @baz.update_attributes(:other => "Lorem ipsum dolor sit amet")
207
- @baz.to_param.should eql former_slug
208
- end
209
-
210
- it "does not update slug if slugged fields have changed but generated slug is the same" do
211
- former_slug = @baz.to_param
212
- @baz.update_attributes(:name => "BAZ")
213
- @baz.to_param.should eql former_slug
214
- end
215
-
216
- it "finds by slug" do
217
- @bar.bazes.where(:slug => @baz.to_param).first.should eql @baz
218
- end
219
-
220
- end
221
-
222
- context ":as option" do
223
-
224
- before(:each) do
225
- @person = Person.create(:name => "John Doe")
226
- end
227
-
228
- it "should set the slug field name" do
229
- @person.respond_to?(:permalink).should be_true
230
- @person.send(:permalink).should eql "john-doe"
231
- end
232
-
233
- it "generates slug" do
234
- @person.to_param.should eql(@person.name.parameterize)
235
- end
236
-
237
- it "updates slug" do
238
- @person.update_attributes(:name => "Jane Doe")
239
- @person.to_param.should eql "Jane Doe".parameterize
240
- end
241
-
242
- it "generates a unique slug" do
243
- similar_person = Person.create(:name => @person.name)
244
- similar_person.to_param.should_not eql @person.to_param
245
- end
246
-
247
- it "appends a counter when slug is not unique" do
248
- similar_person = Person.create(:name => @person.name)
249
- similar_person.to_param.should match /\d$/
250
- end
251
-
252
- it "does not append a counter when slug is unique" do
253
- @person.to_param.should_not match /\d$/
254
- end
255
-
256
- it "does not update slug if slugged fields have not changed" do
257
- former_slug = @person.to_param
258
- @person.update_attributes(:age => 31)
259
- @person.to_param.should eql former_slug
260
- end
261
-
262
- it "does not update slug if slugged fields have changed but generated slug is the same" do
263
- former_slug = @person.to_param
264
- @person.update_attributes(:name => "JOHN DOE")
265
- @person.to_param.should eql former_slug
266
- end
267
-
268
- it "finds by slug" do
269
- Person.where(:permalink => @person.to_param).first.should eql @person
270
- end
271
-
272
- end
273
-
274
- context "#find_" do
275
-
276
- before(:each) do
277
- @foo = Foo.create(:name => "foo")
278
- @bar = @foo.bars.create(:name => "bar")
279
- @baz = @bar.bazes.create(:name => "baz")
280
- end
281
-
282
- it "finds duplicate slug of a root document" do
283
- @foo.send(:find_, @foo.to_param).count.should eql 1
284
- end
285
-
286
- it "finds duplicate slug of an embedded document" do
287
- @bar.send(:find_, @bar.to_param).count.should eql 1
288
- end
289
-
290
- it "finds duplicate slug of a deeply-embedded document" do
291
- @baz.send(:find_, @baz.to_param).count.should eql 1
292
- end
293
-
294
- end
295
-
296
- context ":scoped option" do
297
- before(:each) do
298
- @foo = Foo.create(:name => "foo")
299
- @sar = @foo.sars.create(:name => "sar")
300
- @foo2 = Foo.create(:name => "foo")
301
- end
302
-
303
- it "generates a unique slug inside the same parent object" do
304
- similar_sar = @foo.sars.create(:name => @sar.name)
305
- similar_sar.to_param.should_not eql @sar.to_param
306
- end
307
-
308
- it "generates the same slug in different parent object" do
309
- other_sar = @foo2.sars.create(:name => @sar.name)
310
- other_sar.to_param.should eql @sar.to_param
311
- end
312
- end
313
-
314
- end