mongoid_slug 0.4.6 → 0.4.7

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