mongoid_slug 3.1.1 → 3.1.2
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.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/lib/mongoid/slug.rb +70 -8
- data/lib/mongoid/slug/unique_slug.rb +5 -5
- data/lib/mongoid/slug/version.rb +1 -1
- data/spec/models/page_slug_localized.rb +1 -1
- data/spec/models/page_slug_localized_history.rb +1 -1
- data/spec/mongoid/criteria_spec.rb +190 -0
- data/spec/mongoid/slug_spec.rb +159 -237
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae9fab25b8db6880157df5b1fcab5608336cfe9e
|
4
|
+
data.tar.gz: e8cd36c3abc7acb9b1850e17feff903d4c965743
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21ee51edcd378221ba9057a806d4d3c609df8704a1c297145e3c72c8439d0a4266e4947faed5f8b8d487042b73bdd7759cab0618e001f5c2d957123d331509fc
|
7
|
+
data.tar.gz: 0a11a12f37b1b45a855ba89ca854b16adb71e184db4ca2c1a5799e9c50c511acd700807551a432f8224c4d29c912357e35b5576dccc13a29e9391e30f691f7f2
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Mongoid Slug generates a URL slug or permalink based on one or more fields in a
|
|
8
8
|
Mongoid model. It sits idly on top of [stringex] [1], supporting non-Latin
|
9
9
|
characters.
|
10
10
|
|
11
|
-
[](http://travis-ci.org/digitalplaywright/mongoid-slug)
|
11
|
+
[](http://travis-ci.org/digitalplaywright/mongoid-slug) [](https://gemnasium.com/digitalplaywright/mongoid-slug) [](https://codeclimate.com/github/digitalplaywright/mongoid-slug)
|
12
12
|
|
13
13
|
Installation
|
14
14
|
------------
|
@@ -235,13 +235,13 @@ Specifying an array of custom reserved words will overwrite these defaults.
|
|
235
235
|
Localize Slug
|
236
236
|
--------------
|
237
237
|
|
238
|
-
The slug can be localized:
|
238
|
+
The slug can be localized:
|
239
239
|
|
240
240
|
```ruby
|
241
241
|
class PageSlugLocalize
|
242
242
|
include Mongoid::Document
|
243
243
|
include Mongoid::Slug
|
244
|
-
|
244
|
+
|
245
245
|
field :title, localize: true
|
246
246
|
slug :title, localize: true
|
247
247
|
end
|
@@ -250,7 +250,7 @@ end
|
|
250
250
|
This feature is built upon Mongoid localized fields, so fallbacks and localization
|
251
251
|
works as documented in the Mongoid manual.
|
252
252
|
|
253
|
-
PS! A migration is needed to use Mongoid localized fields for documents that was created when this
|
253
|
+
PS! A migration is needed to use Mongoid localized fields for documents that was created when this
|
254
254
|
feature was off. Anything else will cause errors.
|
255
255
|
|
256
256
|
Custom Find Strategies
|
data/lib/mongoid/slug.rb
CHANGED
@@ -64,7 +64,7 @@ module Mongoid
|
|
64
64
|
scope_key = (metadata = self.reflect_on_association(slug_scope)) ? metadata.key : slug_scope
|
65
65
|
if options[:by_model_type] == true
|
66
66
|
# Add _type to the index to fix polymorphism
|
67
|
-
index({ _type: 1, scope_key => 1, _slugs: 1}
|
67
|
+
index({ _type: 1, scope_key => 1, _slugs: 1})
|
68
68
|
else
|
69
69
|
index({scope_key => 1, _slugs: 1}, {unique: true})
|
70
70
|
end
|
@@ -72,7 +72,7 @@ module Mongoid
|
|
72
72
|
else
|
73
73
|
# Add _type to the index to fix polymorphism
|
74
74
|
if options[:by_model_type] == true
|
75
|
-
index({_type: 1, _slugs: 1}
|
75
|
+
index({_type: 1, _slugs: 1})
|
76
76
|
else
|
77
77
|
index({_slugs: 1}, {unique: true})
|
78
78
|
end
|
@@ -130,22 +130,39 @@ module Mongoid
|
|
130
130
|
#
|
131
131
|
# @return [true]
|
132
132
|
def build_slug
|
133
|
+
if localized?
|
134
|
+
begin
|
135
|
+
orig_locale = I18n.locale
|
136
|
+
all_locales = self.slugged_attributes
|
137
|
+
.map{|attr| self.send("#{attr}_translations").keys}.flatten.uniq
|
138
|
+
all_locales.each do |target_locale|
|
139
|
+
I18n.locale = target_locale
|
140
|
+
set_slug
|
141
|
+
end
|
142
|
+
ensure
|
143
|
+
I18n.locale = orig_locale
|
144
|
+
end
|
145
|
+
else
|
146
|
+
set_slug
|
147
|
+
end
|
148
|
+
true
|
149
|
+
end
|
150
|
+
|
151
|
+
def set_slug
|
133
152
|
_new_slug = find_unique_slug
|
134
153
|
|
135
154
|
#skip slug generation and use Mongoid id
|
136
155
|
#to find document instead
|
137
156
|
return true if _new_slug.size == 0
|
138
157
|
|
158
|
+
# avoid duplicate slugs
|
139
159
|
self._slugs.delete(_new_slug) if self._slugs
|
140
160
|
|
141
161
|
if !!self.history && self._slugs.is_a?(Array)
|
142
|
-
|
162
|
+
append_slug(_new_slug)
|
143
163
|
else
|
144
164
|
self._slugs = [_new_slug]
|
145
165
|
end
|
146
|
-
|
147
|
-
true
|
148
|
-
|
149
166
|
end
|
150
167
|
|
151
168
|
# Finds a unique slug, were specified string used to generate a slug.
|
@@ -181,16 +198,61 @@ module Mongoid
|
|
181
198
|
|
182
199
|
def slug_builder
|
183
200
|
_cur_slug = nil
|
184
|
-
if
|
201
|
+
if new_with_slugs? or persisted_with_slug_changes?
|
185
202
|
#user defined slug
|
186
|
-
_cur_slug =
|
203
|
+
_cur_slug = _slugs.last
|
187
204
|
end
|
188
205
|
#generate slug if the slug is not user defined or does not exist
|
189
206
|
_cur_slug || pre_slug_string
|
190
207
|
end
|
191
208
|
|
209
|
+
|
210
|
+
|
192
211
|
private
|
193
212
|
|
213
|
+
def append_slug(_slug)
|
214
|
+
if localized?
|
215
|
+
# This is necessary for the scenario in which the slugged locale is not yet present
|
216
|
+
# but the default locale is. In this situation, self._slugs falls back to the default
|
217
|
+
# which is undesired
|
218
|
+
current_slugs = self._slugs_translations.fetch(I18n.locale.to_s, [])
|
219
|
+
current_slugs << _slug
|
220
|
+
self._slugs_translations = self._slugs_translations.merge(I18n.locale.to_s => current_slugs)
|
221
|
+
else
|
222
|
+
self._slugs << _slug
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Returns true if object is a new record and slugs are present
|
227
|
+
def new_with_slugs?
|
228
|
+
if localized?
|
229
|
+
# We need to check if slugs are present for the locale without falling back
|
230
|
+
# to a default
|
231
|
+
new_record? and _slugs_translations.fetch(I18n.locale.to_s, []).any?
|
232
|
+
else
|
233
|
+
new_record? and _slugs.present?
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Returns true if object has been persisted and has changes in the slug
|
238
|
+
def persisted_with_slug_changes?
|
239
|
+
if localized?
|
240
|
+
changes = self._slugs_change
|
241
|
+
return (persisted? and false) if changes.nil?
|
242
|
+
|
243
|
+
# ensure we check for changes only between the same locale
|
244
|
+
original = changes.first.try(:fetch, I18n.locale.to_s, nil)
|
245
|
+
compare = changes.last.try(:fetch, I18n.locale.to_s, nil)
|
246
|
+
persisted? and original != compare
|
247
|
+
else
|
248
|
+
persisted? and _slugs_changed?
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def localized?
|
253
|
+
self.fields['_slugs'].options[:localize] rescue false
|
254
|
+
end
|
255
|
+
|
194
256
|
def pre_slug_string
|
195
257
|
self.slugged_attributes.map { |f| self.send f }.join ' '
|
196
258
|
end
|
@@ -80,7 +80,7 @@ module Mongoid
|
|
80
80
|
# Regular expression that matches slug, slug-1, ... slug-n
|
81
81
|
# If slug_name field was indexed, MongoDB will utilize that
|
82
82
|
# index to match /^.../ pattern.
|
83
|
-
pattern = /^#{Regexp.escape(_slug)}(?:-(\d+))?$/
|
83
|
+
pattern = /^#{Regexp.escape(@_slug)}(?:-(\d+))?$/
|
84
84
|
|
85
85
|
where_hash = {}
|
86
86
|
where_hash[:_slugs.all] = [pattern]
|
@@ -96,13 +96,13 @@ module Mongoid
|
|
96
96
|
where_hash[:_type] = model.try(:read_attribute, :_type)
|
97
97
|
end
|
98
98
|
|
99
|
-
@state = SlugState.new _slug, uniqueness_scope.unscoped.where(where_hash), pattern
|
99
|
+
@state = SlugState.new @_slug, uniqueness_scope.unscoped.where(where_hash), pattern
|
100
100
|
|
101
101
|
# do not allow a slug that can be interpreted as the current document id
|
102
|
-
@state.include_slug unless model.class.look_like_slugs?([_slug])
|
102
|
+
@state.include_slug unless model.class.look_like_slugs?([@_slug])
|
103
103
|
|
104
104
|
# make sure that the slug is not equal to a reserved word
|
105
|
-
@state.include_slug if reserved_words.any? { |word| word === _slug }
|
105
|
+
@state.include_slug if reserved_words.any? { |word| word === @_slug }
|
106
106
|
|
107
107
|
# only look for a new unique slug if the existing slugs contains the current slug
|
108
108
|
# - e.g if the slug 'foo-2' is taken, but 'foo' is available, the user can use 'foo'.
|
@@ -110,7 +110,7 @@ module Mongoid
|
|
110
110
|
highest = @state.highest_existing_counter
|
111
111
|
@_slug += "-#{highest.succ}"
|
112
112
|
end
|
113
|
-
_slug
|
113
|
+
@_slug
|
114
114
|
end
|
115
115
|
|
116
116
|
def uniqueness_scope
|
data/lib/mongoid/slug/version.rb
CHANGED
@@ -0,0 +1,190 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe Mongoid::Slug::Criteria do
|
5
|
+
describe ".find" do
|
6
|
+
let!(:book) { Book.create(:title => "A Working Title").tap { |d| d.update_attribute(:title, "A Thousand Plateaus") } }
|
7
|
+
let!(:book2) { Book.create(:title => "Difference and Repetition") }
|
8
|
+
let!(:friend) { Friend.create(:name => "Jim Bob") }
|
9
|
+
let!(:friend2) { Friend.create(:name => friend.id.to_s) }
|
10
|
+
let!(:integer_id) { IntegerId.new(:name => "I have integer ids").tap { |d| d.id = 123; d.save } }
|
11
|
+
let!(:integer_id2) { IntegerId.new(:name => integer_id.id.to_s).tap { |d| d.id = 456; d.save } }
|
12
|
+
let!(:string_id) { StringId.new(:name => "I have string ids").tap { |d| d.id = 'abc'; d.save } }
|
13
|
+
let!(:string_id2) { StringId.new(:name => string_id.id.to_s).tap { |d| d.id = 'def'; d.save } }
|
14
|
+
let!(:subject) { Subject.create(:name => "A Subject", :book => book) }
|
15
|
+
let!(:subject2) { Subject.create(:name => "A Subject", :book => book2) }
|
16
|
+
let!(:without_slug) { WithoutSlug.new().tap { |d| d.id = 456; d.save } }
|
17
|
+
|
18
|
+
context "when the model does not use mongoid slugs" do
|
19
|
+
it "should not use mongoid slug's custom find methods" do
|
20
|
+
Mongoid::Slug::Criteria.any_instance.should_not_receive(:find)
|
21
|
+
WithoutSlug.find(without_slug.id.to_s).should == without_slug
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "using slugs" do
|
26
|
+
context "(single)" do
|
27
|
+
context "and a document is found" do
|
28
|
+
it "returns the document as an object" do
|
29
|
+
Book.find(book.slugs.first).should == book
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "but no document is found" do
|
34
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
35
|
+
lambda {
|
36
|
+
Book.find("Anti Oedipus")
|
37
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "(multiple)" do
|
43
|
+
context "and all documents are found" do
|
44
|
+
it "returns the documents as an array without duplication" do
|
45
|
+
Book.find(book.slugs + book2.slugs).should =~ [book, book2]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "but not all documents are found" do
|
50
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
51
|
+
lambda {
|
52
|
+
Book.find(book.slugs + ['something-nonexistent'])
|
53
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when no documents match" do
|
59
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
60
|
+
lambda {
|
61
|
+
Book.find("Anti Oedipus")
|
62
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when ids are BSON::ObjectIds and the supplied argument looks like a BSON::ObjectId" do
|
67
|
+
it "it should find based on ids not slugs" do # i.e. it should type cast the argument
|
68
|
+
Friend.find(friend.id.to_s).should == friend
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when ids are Strings" do
|
73
|
+
it "it should find based on ids not slugs" do # i.e. string ids should take precedence over string slugs
|
74
|
+
StringId.find(string_id.id.to_s).should == string_id
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when ids are Integers and the supplied arguments looks like an Integer" do
|
79
|
+
it "it should find based on slugs not ids" do # i.e. it should not type cast the argument
|
80
|
+
IntegerId.find(integer_id.id.to_s).should == integer_id2
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "models that does not use slugs, should find using the original find" do
|
85
|
+
it "it should find based on ids" do # i.e. it should not type cast the argument
|
86
|
+
WithoutSlug.find(without_slug.id.to_s).should == without_slug
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when scoped" do
|
91
|
+
context "and a document is found" do
|
92
|
+
it "returns the document as an object" do
|
93
|
+
book.subjects.find(subject.slugs.first).should == subject
|
94
|
+
book2.subjects.find(subject.slugs.first).should == subject2
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "but no document is found" do
|
99
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
100
|
+
lambda {
|
101
|
+
book.subjects.find('Another Subject')
|
102
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "using ids" do
|
109
|
+
it "raises a Mongoid::Errors::DocumentNotFound error if no document is found" do
|
110
|
+
lambda {
|
111
|
+
Book.find(friend.id)
|
112
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
113
|
+
end
|
114
|
+
|
115
|
+
context "given a single document" do
|
116
|
+
it "returns the document" do
|
117
|
+
Friend.find(friend.id).should == friend
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "given multiple documents" do
|
122
|
+
it "returns the documents" do
|
123
|
+
Book.find([book.id, book2.id]).should =~ [book, book2]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe ".find_by_slug!" do
|
130
|
+
let!(:book) { Book.create(:title => "A Working Title").tap { |d| d.update_attribute(:title, "A Thousand Plateaus") } }
|
131
|
+
let!(:book2) { Book.create(:title => "Difference and Repetition") }
|
132
|
+
let!(:friend) { Friend.create(:name => "Jim Bob") }
|
133
|
+
let!(:friend2) { Friend.create(:name => friend.id.to_s) }
|
134
|
+
let!(:integer_id) { IntegerId.new(:name => "I have integer ids").tap { |d| d.id = 123; d.save } }
|
135
|
+
let!(:integer_id2) { IntegerId.new(:name => integer_id.id.to_s).tap { |d| d.id = 456; d.save } }
|
136
|
+
let!(:string_id) { StringId.new(:name => "I have string ids").tap { |d| d.id = 'abc'; d.save } }
|
137
|
+
let!(:string_id2) { StringId.new(:name => string_id.id.to_s).tap { |d| d.id = 'def'; d.save } }
|
138
|
+
let!(:subject) { Subject.create(:name => "A Subject", :book => book) }
|
139
|
+
let!(:subject2) { Subject.create(:name => "A Subject", :book => book2) }
|
140
|
+
|
141
|
+
context "(single)" do
|
142
|
+
context "and a document is found" do
|
143
|
+
it "returns the document as an object" do
|
144
|
+
Book.find_by_slug!(book.slugs.first).should == book
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "but no document is found" do
|
149
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
150
|
+
lambda {
|
151
|
+
Book.find_by_slug!("Anti Oedipus")
|
152
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "(multiple)" do
|
158
|
+
context "and all documents are found" do
|
159
|
+
it "returns the documents as an array without duplication" do
|
160
|
+
Book.find_by_slug!(book.slugs + book2.slugs).should =~ [book, book2]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "but not all documents are found" do
|
165
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
166
|
+
lambda {
|
167
|
+
Book.find_by_slug!(book.slugs + ['something-nonexistent'])
|
168
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when scoped" do
|
174
|
+
context "and a document is found" do
|
175
|
+
it "returns the document as an object" do
|
176
|
+
book.subjects.find_by_slug!(subject.slugs.first).should == subject
|
177
|
+
book2.subjects.find_by_slug!(subject.slugs.first).should == subject2
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "but no document is found" do
|
182
|
+
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
183
|
+
lambda {
|
184
|
+
book.subjects.find_by_slug!('Another Subject')
|
185
|
+
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
data/spec/mongoid/slug_spec.rb
CHANGED
@@ -544,7 +544,7 @@ module Mongoid
|
|
544
544
|
end
|
545
545
|
|
546
546
|
it "defines a unique index" do
|
547
|
-
BookPolymorphic.index_options[ :_type => 1, :_slugs => 1 ][:unique].
|
547
|
+
BookPolymorphic.index_options[ :_type => 1, :_slugs => 1 ][:unique].should_not be_true
|
548
548
|
end
|
549
549
|
end
|
550
550
|
|
@@ -642,192 +642,6 @@ module Mongoid
|
|
642
642
|
end
|
643
643
|
end
|
644
644
|
|
645
|
-
describe ".find" do
|
646
|
-
let!(:book) { Book.create(:title => "A Working Title").tap { |d| d.update_attribute(:title, "A Thousand Plateaus") } }
|
647
|
-
let!(:book2) { Book.create(:title => "Difference and Repetition") }
|
648
|
-
let!(:friend) { Friend.create(:name => "Jim Bob") }
|
649
|
-
let!(:friend2) { Friend.create(:name => friend.id.to_s) }
|
650
|
-
let!(:integer_id) { IntegerId.new(:name => "I have integer ids").tap { |d| d.id = 123; d.save } }
|
651
|
-
let!(:integer_id2) { IntegerId.new(:name => integer_id.id.to_s).tap { |d| d.id = 456; d.save } }
|
652
|
-
let!(:string_id) { StringId.new(:name => "I have string ids").tap { |d| d.id = 'abc'; d.save } }
|
653
|
-
let!(:string_id2) { StringId.new(:name => string_id.id.to_s).tap { |d| d.id = 'def'; d.save } }
|
654
|
-
let!(:subject) { Subject.create(:name => "A Subject", :book => book) }
|
655
|
-
let!(:subject2) { Subject.create(:name => "A Subject", :book => book2) }
|
656
|
-
let!(:without_slug) { WithoutSlug.new().tap { |d| d.id = 456; d.save } }
|
657
|
-
|
658
|
-
context "when the model does not use mongoid slugs" do
|
659
|
-
it "should not use mongoid slug's custom find methods" do
|
660
|
-
Mongoid::Slug::Criteria.any_instance.should_not_receive(:find)
|
661
|
-
WithoutSlug.find(without_slug.id.to_s).should == without_slug
|
662
|
-
end
|
663
|
-
end
|
664
|
-
|
665
|
-
context "using slugs" do
|
666
|
-
context "(single)" do
|
667
|
-
context "and a document is found" do
|
668
|
-
it "returns the document as an object" do
|
669
|
-
Book.find(book.slugs.first).should == book
|
670
|
-
end
|
671
|
-
end
|
672
|
-
|
673
|
-
context "but no document is found" do
|
674
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
675
|
-
lambda {
|
676
|
-
Book.find("Anti Oedipus")
|
677
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
678
|
-
end
|
679
|
-
end
|
680
|
-
end
|
681
|
-
|
682
|
-
context "(multiple)" do
|
683
|
-
context "and all documents are found" do
|
684
|
-
it "returns the documents as an array without duplication" do
|
685
|
-
Book.find(book.slugs + book2.slugs).should =~ [book, book2]
|
686
|
-
end
|
687
|
-
end
|
688
|
-
|
689
|
-
context "but not all documents are found" do
|
690
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
691
|
-
lambda {
|
692
|
-
Book.find(book.slugs + ['something-nonexistent'])
|
693
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
694
|
-
end
|
695
|
-
end
|
696
|
-
end
|
697
|
-
|
698
|
-
context "when no documents match" do
|
699
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
700
|
-
lambda {
|
701
|
-
Book.find("Anti Oedipus")
|
702
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
703
|
-
end
|
704
|
-
end
|
705
|
-
|
706
|
-
context "when ids are BSON::ObjectIds and the supplied argument looks like a BSON::ObjectId" do
|
707
|
-
it "it should find based on ids not slugs" do # i.e. it should type cast the argument
|
708
|
-
Friend.find(friend.id.to_s).should == friend
|
709
|
-
end
|
710
|
-
end
|
711
|
-
|
712
|
-
context "when ids are Strings" do
|
713
|
-
it "it should find based on ids not slugs" do # i.e. string ids should take precedence over string slugs
|
714
|
-
StringId.find(string_id.id.to_s).should == string_id
|
715
|
-
end
|
716
|
-
end
|
717
|
-
|
718
|
-
context "when ids are Integers and the supplied arguments looks like an Integer" do
|
719
|
-
it "it should find based on slugs not ids" do # i.e. it should not type cast the argument
|
720
|
-
IntegerId.find(integer_id.id.to_s).should == integer_id2
|
721
|
-
end
|
722
|
-
end
|
723
|
-
|
724
|
-
context "models that does not use slugs, should find using the original find" do
|
725
|
-
it "it should find based on ids" do # i.e. it should not type cast the argument
|
726
|
-
WithoutSlug.find(without_slug.id.to_s).should == without_slug
|
727
|
-
end
|
728
|
-
end
|
729
|
-
|
730
|
-
context "when scoped" do
|
731
|
-
context "and a document is found" do
|
732
|
-
it "returns the document as an object" do
|
733
|
-
book.subjects.find(subject.slugs.first).should == subject
|
734
|
-
book2.subjects.find(subject.slugs.first).should == subject2
|
735
|
-
end
|
736
|
-
end
|
737
|
-
|
738
|
-
context "but no document is found" do
|
739
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
740
|
-
lambda {
|
741
|
-
book.subjects.find('Another Subject')
|
742
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
743
|
-
end
|
744
|
-
end
|
745
|
-
end
|
746
|
-
end
|
747
|
-
|
748
|
-
context "using ids" do
|
749
|
-
it "raises a Mongoid::Errors::DocumentNotFound error if no document is found" do
|
750
|
-
lambda {
|
751
|
-
Book.find(friend.id)
|
752
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
753
|
-
end
|
754
|
-
|
755
|
-
context "given a single document" do
|
756
|
-
it "returns the document" do
|
757
|
-
Friend.find(friend.id).should == friend
|
758
|
-
end
|
759
|
-
end
|
760
|
-
|
761
|
-
context "given multiple documents" do
|
762
|
-
it "returns the documents" do
|
763
|
-
Book.find([book.id, book2.id]).should =~ [book, book2]
|
764
|
-
end
|
765
|
-
end
|
766
|
-
end
|
767
|
-
end
|
768
|
-
|
769
|
-
describe ".find_by_slug!" do
|
770
|
-
let!(:book) { Book.create(:title => "A Working Title").tap { |d| d.update_attribute(:title, "A Thousand Plateaus") } }
|
771
|
-
let!(:book2) { Book.create(:title => "Difference and Repetition") }
|
772
|
-
let!(:friend) { Friend.create(:name => "Jim Bob") }
|
773
|
-
let!(:friend2) { Friend.create(:name => friend.id.to_s) }
|
774
|
-
let!(:integer_id) { IntegerId.new(:name => "I have integer ids").tap { |d| d.id = 123; d.save } }
|
775
|
-
let!(:integer_id2) { IntegerId.new(:name => integer_id.id.to_s).tap { |d| d.id = 456; d.save } }
|
776
|
-
let!(:string_id) { StringId.new(:name => "I have string ids").tap { |d| d.id = 'abc'; d.save } }
|
777
|
-
let!(:string_id2) { StringId.new(:name => string_id.id.to_s).tap { |d| d.id = 'def'; d.save } }
|
778
|
-
let!(:subject) { Subject.create(:name => "A Subject", :book => book) }
|
779
|
-
let!(:subject2) { Subject.create(:name => "A Subject", :book => book2) }
|
780
|
-
|
781
|
-
context "(single)" do
|
782
|
-
context "and a document is found" do
|
783
|
-
it "returns the document as an object" do
|
784
|
-
Book.find_by_slug!(book.slugs.first).should == book
|
785
|
-
end
|
786
|
-
end
|
787
|
-
|
788
|
-
context "but no document is found" do
|
789
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
790
|
-
lambda {
|
791
|
-
Book.find_by_slug!("Anti Oedipus")
|
792
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
793
|
-
end
|
794
|
-
end
|
795
|
-
end
|
796
|
-
|
797
|
-
context "(multiple)" do
|
798
|
-
context "and all documents are found" do
|
799
|
-
it "returns the documents as an array without duplication" do
|
800
|
-
Book.find_by_slug!(book.slugs + book2.slugs).should =~ [book, book2]
|
801
|
-
end
|
802
|
-
end
|
803
|
-
|
804
|
-
context "but not all documents are found" do
|
805
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
806
|
-
lambda {
|
807
|
-
Book.find_by_slug!(book.slugs + ['something-nonexistent'])
|
808
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
809
|
-
end
|
810
|
-
end
|
811
|
-
end
|
812
|
-
|
813
|
-
context "when scoped" do
|
814
|
-
context "and a document is found" do
|
815
|
-
it "returns the document as an object" do
|
816
|
-
book.subjects.find_by_slug!(subject.slugs.first).should == subject
|
817
|
-
book2.subjects.find_by_slug!(subject.slugs.first).should == subject2
|
818
|
-
end
|
819
|
-
end
|
820
|
-
|
821
|
-
context "but no document is found" do
|
822
|
-
it "raises a Mongoid::Errors::DocumentNotFound error" do
|
823
|
-
lambda {
|
824
|
-
book.subjects.find_by_slug!('Another Subject')
|
825
|
-
}.should raise_error(Mongoid::Errors::DocumentNotFound)
|
826
|
-
end
|
827
|
-
end
|
828
|
-
end
|
829
|
-
end
|
830
|
-
|
831
645
|
describe "#to_param" do
|
832
646
|
context "when called on a new record" do
|
833
647
|
let(:book) { Book.new }
|
@@ -938,11 +752,16 @@ module Mongoid
|
|
938
752
|
end
|
939
753
|
|
940
754
|
context "slug can be localized" do
|
941
|
-
|
942
|
-
old_locale = I18n.locale
|
755
|
+
before(:each) do
|
756
|
+
@old_locale = I18n.locale
|
757
|
+
end
|
943
758
|
|
944
|
-
|
945
|
-
|
759
|
+
after(:each) do
|
760
|
+
I18n.locale = @old_locale
|
761
|
+
end
|
762
|
+
|
763
|
+
it "generates a new slug for each localization" do
|
764
|
+
page = PageSlugLocalized.new
|
946
765
|
page.title = "Title on English"
|
947
766
|
page.save
|
948
767
|
page.slug.should eql "title-on-english"
|
@@ -950,31 +769,19 @@ module Mongoid
|
|
950
769
|
page.title = "Title on Netherlands"
|
951
770
|
page.save
|
952
771
|
page.slug.should eql "title-on-netherlands"
|
953
|
-
|
954
|
-
# Set locale back to english
|
955
|
-
I18n.locale = old_locale
|
956
772
|
end
|
957
773
|
|
958
774
|
it "returns _id if no slug" do
|
959
|
-
|
960
|
-
|
961
|
-
# Using a default locale of en.
|
962
|
-
page = PageSlugLocalize.new
|
775
|
+
page = PageSlugLocalized.new
|
963
776
|
page.title = "Title on English"
|
964
777
|
page.save
|
965
778
|
page.slug.should eql "title-on-english"
|
966
779
|
I18n.locale = :nl
|
967
780
|
page.slug.should eql page._id.to_s
|
968
|
-
|
969
|
-
# Set locale back to english
|
970
|
-
I18n.locale = old_locale
|
971
781
|
end
|
972
782
|
|
973
783
|
it "fallbacks if slug not localized yet" do
|
974
|
-
|
975
|
-
|
976
|
-
# Using a default locale of en.
|
977
|
-
page = PageSlugLocalize.new
|
784
|
+
page = PageSlugLocalized.new
|
978
785
|
page.title = "Title on English"
|
979
786
|
page.save
|
980
787
|
page.slug.should eql "title-on-english"
|
@@ -988,20 +795,14 @@ module Mongoid
|
|
988
795
|
page.slug.should eql "title-on-english"
|
989
796
|
fallback_slug = page.slug
|
990
797
|
|
991
|
-
fallback_page =
|
798
|
+
fallback_page = PageSlugLocalized.find(fallback_slug) rescue nil
|
992
799
|
fallback_page.should eq(page)
|
993
800
|
|
994
|
-
# Set locale back to english
|
995
|
-
I18n.locale = old_locale
|
996
|
-
|
997
801
|
# Restore fallback for next tests
|
998
802
|
::I18n.fallbacks[:nl] = [ :nl ]
|
999
803
|
end
|
1000
804
|
|
1001
|
-
it "returns default slug if not localized" do
|
1002
|
-
old_locale = I18n.locale
|
1003
|
-
|
1004
|
-
# Using a default locale of en.
|
805
|
+
it "returns a default slug if not localized" do
|
1005
806
|
page = PageLocalize.new
|
1006
807
|
page.title = "Title on English"
|
1007
808
|
page.save
|
@@ -1011,19 +812,88 @@ module Mongoid
|
|
1011
812
|
page.slug.should eql "title-on-english"
|
1012
813
|
page.save
|
1013
814
|
page.slug.should eql "title-on-netherlands"
|
815
|
+
end
|
816
|
+
|
817
|
+
it "slugs properly when translations are set directly" do
|
818
|
+
page = PageSlugLocalized.new
|
819
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
820
|
+
page.save
|
821
|
+
page["_slugs"].should == {"en" => ["title-on-english"], "nl" => ["title-on-netherlands"]}
|
822
|
+
end
|
823
|
+
|
824
|
+
it "does not produce duplicate slugs" do
|
825
|
+
old_locale = I18n.locale
|
1014
826
|
|
827
|
+
# Using a default locale of en.
|
828
|
+
page = PageSlugLocalized.new
|
829
|
+
page.title = "Title on English"
|
830
|
+
page.save
|
831
|
+
I18n.locale = "nl"
|
832
|
+
page.title = "Title on Netherlands"
|
833
|
+
page.save
|
834
|
+
page.title_translations.should == {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
1015
835
|
|
1016
|
-
# Set locale back to english
|
1017
836
|
I18n.locale = old_locale
|
837
|
+
page.title = "Title on English"
|
838
|
+
page.title_translations.should == {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
839
|
+
page["_slugs"].should == {"en" => ["title-on-english"], "nl" => ["title-on-netherlands"]}
|
840
|
+
end
|
841
|
+
|
842
|
+
it "does not produce duplicate slugs when one has changed" do
|
843
|
+
old_locale = I18n.locale
|
844
|
+
|
845
|
+
# Using a default locale of en.
|
846
|
+
page = PageSlugLocalized.new
|
847
|
+
page.title = "Title on English"
|
848
|
+
page.save
|
849
|
+
I18n.locale = "nl"
|
850
|
+
page.title = "Title on Netherlands"
|
851
|
+
page.save
|
852
|
+
page.title_translations.should == {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
853
|
+
|
854
|
+
I18n.locale = old_locale
|
855
|
+
page.title = "Modified Title on English"
|
856
|
+
page.save
|
857
|
+
page.title_translations.should == {"en" => "Modified Title on English",
|
858
|
+
"nl" => "Title on Netherlands"}
|
859
|
+
page["_slugs"].should == {"en" => ["modified-title-on-english"],
|
860
|
+
"nl" => ["title-on-netherlands"]}
|
861
|
+
end
|
862
|
+
|
863
|
+
it "does not produce duplicate slugs when transactions are set directly" do
|
864
|
+
page = PageSlugLocalized.new
|
865
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
866
|
+
page.save
|
867
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
868
|
+
page.save
|
869
|
+
page["_slugs"].should == {"en" => ["title-on-english"], "nl" => ["title-on-netherlands"]}
|
870
|
+
end
|
871
|
+
|
872
|
+
it "does not produce duplicate slugs when transactions are set directly and one has changed" do
|
873
|
+
page = PageSlugLocalized.new
|
874
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
875
|
+
page.save
|
876
|
+
page.title_translations = {"en" => "Modified Title on English",
|
877
|
+
"nl" => "Title on Netherlands"}
|
878
|
+
page.save
|
879
|
+
page["_slugs"].should == {"en" => ["modified-title-on-english"],
|
880
|
+
"nl" => ["title-on-netherlands"]}
|
1018
881
|
end
|
1019
882
|
end
|
1020
883
|
|
1021
884
|
context "slug can be localized when using history" do
|
885
|
+
before(:each) do
|
886
|
+
@old_locale = I18n.locale
|
887
|
+
end
|
888
|
+
|
889
|
+
after(:each) do
|
890
|
+
I18n.locale = @old_locale
|
891
|
+
end
|
892
|
+
|
1022
893
|
it "generate a new slug for each localization and keep history" do
|
1023
894
|
old_locale = I18n.locale
|
1024
895
|
|
1025
|
-
|
1026
|
-
page = PageSlugLocalizeHistory.new
|
896
|
+
page = PageSlugLocalizedHistory.new
|
1027
897
|
page.title = "Title on English"
|
1028
898
|
page.save
|
1029
899
|
page.slug.should eql "title-on-english"
|
@@ -1041,31 +911,19 @@ module Mongoid
|
|
1041
911
|
page.save
|
1042
912
|
page.slug.should eql "modified-title-on-netherlands"
|
1043
913
|
page.slug.should include("title-on-netherlands")
|
1044
|
-
|
1045
|
-
# Set locale back to english
|
1046
|
-
I18n.locale = old_locale
|
1047
914
|
end
|
1048
915
|
|
1049
916
|
it "returns _id if no slug" do
|
1050
|
-
|
1051
|
-
|
1052
|
-
# Using a default locale of en.
|
1053
|
-
page = PageSlugLocalizeHistory.new
|
917
|
+
page = PageSlugLocalizedHistory.new
|
1054
918
|
page.title = "Title on English"
|
1055
919
|
page.save
|
1056
920
|
page.slug.should eql "title-on-english"
|
1057
921
|
I18n.locale = :nl
|
1058
922
|
page.slug.should eql page._id.to_s
|
1059
|
-
|
1060
|
-
# Set locale back to english
|
1061
|
-
I18n.locale = old_locale
|
1062
923
|
end
|
1063
924
|
|
1064
925
|
it "fallbacks if slug not localized yet" do
|
1065
|
-
|
1066
|
-
|
1067
|
-
# Using a default locale of en.
|
1068
|
-
page = PageSlugLocalizeHistory.new
|
926
|
+
page = PageSlugLocalizedHistory.new
|
1069
927
|
page.title = "Title on English"
|
1070
928
|
page.save
|
1071
929
|
page.slug.should eql "title-on-english"
|
@@ -1079,12 +937,79 @@ module Mongoid
|
|
1079
937
|
page.slug.should eql "title-on-english"
|
1080
938
|
fallback_slug = page.slug
|
1081
939
|
|
1082
|
-
fallback_page =
|
940
|
+
fallback_page = PageSlugLocalizedHistory.find(fallback_slug) rescue nil
|
1083
941
|
fallback_page.should eq(page)
|
942
|
+
end
|
943
|
+
|
944
|
+
it "slugs properly when translations are set directly" do
|
945
|
+
page = PageSlugLocalizedHistory.new
|
946
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
947
|
+
page.save
|
948
|
+
page.title_translations = {"en" => "Modified Title on English",
|
949
|
+
"nl" => "Modified Title on Netherlands"}
|
950
|
+
page.save
|
951
|
+
page["_slugs"].should == {"en" => ["title-on-english", "modified-title-on-english"],
|
952
|
+
"nl" => ["title-on-netherlands", "modified-title-on-netherlands"]}
|
953
|
+
end
|
954
|
+
|
955
|
+
it "does not produce duplicate slugs" do
|
956
|
+
old_locale = I18n.locale
|
957
|
+
|
958
|
+
# Using a default locale of en.
|
959
|
+
page = PageSlugLocalizedHistory.new
|
960
|
+
page.title = "Title on English"
|
961
|
+
page.save
|
962
|
+
I18n.locale = "nl"
|
963
|
+
page.title = "Title on Netherlands"
|
964
|
+
page.save
|
965
|
+
page.title_translations.should == {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
1084
966
|
|
1085
|
-
# Set locale back to english
|
1086
967
|
I18n.locale = old_locale
|
968
|
+
page.title = "Title on English"
|
969
|
+
page.title_translations.should == {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
970
|
+
page["_slugs"].should == {"en" => ["title-on-english"], "nl" => ["title-on-netherlands"]}
|
1087
971
|
end
|
972
|
+
|
973
|
+
it "does not produce duplicate slugs when one has changed" do
|
974
|
+
old_locale = I18n.locale
|
975
|
+
|
976
|
+
# Using a default locale of en.
|
977
|
+
page = PageSlugLocalizedHistory.new
|
978
|
+
page.title = "Title on English"
|
979
|
+
page.save
|
980
|
+
I18n.locale = "nl"
|
981
|
+
page.title = "Title on Netherlands"
|
982
|
+
page.save
|
983
|
+
page.title_translations.should == {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
984
|
+
|
985
|
+
I18n.locale = old_locale
|
986
|
+
page.title = "Modified Title on English"
|
987
|
+
page.save
|
988
|
+
page.title_translations.should == {"en" => "Modified Title on English",
|
989
|
+
"nl" => "Title on Netherlands"}
|
990
|
+
page["_slugs"].should == {"en" => ["title-on-english", "modified-title-on-english"],
|
991
|
+
"nl" => ["title-on-netherlands"]}
|
992
|
+
end
|
993
|
+
|
994
|
+
it "does not produce duplicate slugs when transactions are set directly" do
|
995
|
+
page = PageSlugLocalizedHistory.new
|
996
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
997
|
+
page.save
|
998
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
999
|
+
page.save
|
1000
|
+
page["_slugs"].should == {"en" => ["title-on-english"], "nl" => ["title-on-netherlands"]}
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
it "does not produce duplicate slugs when transactions are set directly and one has changed" do
|
1004
|
+
page = PageSlugLocalizedHistory.new
|
1005
|
+
page.title_translations = {"en" => "Title on English", "nl" => "Title on Netherlands"}
|
1006
|
+
page.save
|
1007
|
+
page.title_translations = {"en" => "Modified Title on English", "nl" => "Title on Netherlands"}
|
1008
|
+
page.save
|
1009
|
+
page["_slugs"].should == {"en" => ["title-on-english", "modified-title-on-english"],
|
1010
|
+
"nl" => ["title-on-netherlands"]}
|
1011
|
+
end
|
1012
|
+
|
1088
1013
|
end
|
1089
1014
|
|
1090
1015
|
context "Mongoid paranoia with mongoid slug model" do
|
@@ -1092,7 +1017,7 @@ module Mongoid
|
|
1092
1017
|
let(:paranoid_doc) {ParanoidDocument.create!(:title => "slug")}
|
1093
1018
|
|
1094
1019
|
it "returns paranoid_doc for correct slug" do
|
1095
|
-
|
1020
|
+
ParanoidDocument.find(paranoid_doc.slug).should eq(paranoid_doc)
|
1096
1021
|
end
|
1097
1022
|
|
1098
1023
|
it "raises for deleted slug" do
|
@@ -1103,11 +1028,8 @@ module Mongoid
|
|
1103
1028
|
it "returns paranoid_doc for correct restored slug" do
|
1104
1029
|
paranoid_doc.delete
|
1105
1030
|
ParanoidDocument.deleted.first.restore
|
1106
|
-
|
1031
|
+
ParanoidDocument.find(paranoid_doc.slug).should eq(paranoid_doc)
|
1107
1032
|
end
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
1033
|
end
|
1112
1034
|
end
|
1113
1035
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_slug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Saebjoernsen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- spec/models/string_id.rb
|
161
161
|
- spec/models/subject.rb
|
162
162
|
- spec/models/without_slug.rb
|
163
|
+
- spec/mongoid/criteria_spec.rb
|
163
164
|
- spec/mongoid/slug_spec.rb
|
164
165
|
- spec/mongoid/slug_spec.rb.b00
|
165
166
|
- spec/spec_helper.rb
|
@@ -210,6 +211,8 @@ test_files:
|
|
210
211
|
- spec/models/string_id.rb
|
211
212
|
- spec/models/subject.rb
|
212
213
|
- spec/models/without_slug.rb
|
214
|
+
- spec/mongoid/criteria_spec.rb
|
213
215
|
- spec/mongoid/slug_spec.rb
|
214
216
|
- spec/mongoid/slug_spec.rb.b00
|
215
217
|
- spec/spec_helper.rb
|
218
|
+
has_rdoc:
|