mongoid-slug 6.0.0 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +20 -20
- data/README.md +361 -336
- data/lib/mongoid/slug.rb +328 -328
- data/lib/mongoid/slug/criteria.rb +107 -107
- data/lib/mongoid/slug/{index.rb → index_builder.rb} +67 -45
- data/lib/mongoid/slug/railtie.rb +9 -9
- data/lib/mongoid/slug/slug_id_strategy.rb +3 -3
- data/lib/mongoid/slug/unique_slug.rb +173 -173
- data/lib/mongoid/slug/version.rb +5 -5
- data/lib/mongoid_slug.rb +2 -2
- data/lib/tasks/mongoid_slug.rake +15 -19
- data/spec/models/alias.rb +6 -6
- data/spec/models/article.rb +9 -9
- data/spec/models/artist.rb +8 -8
- data/spec/models/artwork.rb +10 -10
- data/spec/models/author.rb +15 -15
- data/spec/models/author_polymorphic.rb +15 -15
- data/spec/models/book.rb +12 -12
- data/spec/models/book_polymorphic.rb +12 -12
- data/spec/models/caption.rb +17 -17
- data/spec/models/entity.rb +11 -11
- data/spec/models/friend.rb +7 -7
- data/spec/models/incorrect_slug_persistence.rb +9 -9
- data/spec/models/integer_id.rb +9 -9
- data/spec/models/magazine.rb +7 -7
- data/spec/models/page.rb +9 -9
- data/spec/models/page_localize.rb +9 -9
- data/spec/models/page_slug_localized.rb +9 -9
- data/spec/models/page_slug_localized_custom.rb +10 -10
- data/spec/models/page_slug_localized_history.rb +9 -9
- data/spec/models/partner.rb +7 -7
- data/spec/models/person.rb +12 -12
- data/spec/models/relationship.rb +8 -8
- data/spec/models/string_id.rb +9 -9
- data/spec/models/subject.rb +7 -7
- data/spec/models/without_slug.rb +5 -5
- data/spec/mongoid/criteria_spec.rb +207 -207
- data/spec/mongoid/index_builder_spec.rb +105 -0
- data/spec/mongoid/slug_spec.rb +1175 -1169
- data/spec/shared/indexes.rb +41 -41
- data/spec/spec_helper.rb +61 -61
- data/spec/tasks/mongoid_slug_rake_spec.rb +73 -73
- metadata +31 -32
- data/spec/mongoid/index_spec.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54274387f9a202810aefa5b3b19c90990636d6076cbc6591cf46129986b4b5e4
|
4
|
+
data.tar.gz: 557ba29c3dfaa615f7e926ba223bb3390e930a52ed559baf33b0517cf224aaa8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11a15aec160529e61f5e6fe9636d9fded847d12ec08fe50e6c67997aca86fed844f42264962c65999e862b7a73ba3d41c337c7fae492e8c91999efbd889ea502
|
7
|
+
data.tar.gz: ff604c15c46fa831bb648906b802cc8e93d13363207fc3a121b7b1c3e4ef3ccb46305f630507ded0e24ad07d70069e4e70ae3185d022267e5ba4c42b53381b44
|
data/LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
Copyright (c) 2010-2017 Hakan Ensari & Contributors
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
Copyright (c) 2010-2017 Hakan Ensari & Contributors
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,336 +1,361 @@
|
|
1
|
-
Mongoid Slug
|
2
|
-
============
|
3
|
-
|
4
|
-
Mongoid Slug generates a URL slug or permalink based on one or more fields in a Mongoid model.
|
5
|
-
|
6
|
-
|
7
|
-
[![
|
8
|
-
[![
|
9
|
-
[![Code Climate](https://codeclimate.com/github/mongoid/mongoid-slug.svg)](https://codeclimate.com/github/mongoid/mongoid-slug)
|
10
|
-
|
11
|
-
### Installation
|
12
|
-
|
13
|
-
Add to your Gemfile:
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
gem 'mongoid-slug'
|
17
|
-
```
|
18
|
-
|
19
|
-
### Usage
|
20
|
-
|
21
|
-
### Set Up a Slug
|
22
|
-
|
23
|
-
```ruby
|
24
|
-
class Book
|
25
|
-
include Mongoid::Document
|
26
|
-
include Mongoid::Slug
|
27
|
-
|
28
|
-
field :title
|
29
|
-
slug :title
|
30
|
-
end
|
31
|
-
```
|
32
|
-
|
33
|
-
### Find a Document by its Slug
|
34
|
-
|
35
|
-
```ruby
|
36
|
-
# GET /books/a-thousand-plateaus
|
37
|
-
book = Book.find params[:book_id]
|
38
|
-
```
|
39
|
-
|
40
|
-
Mongoid Slug will attempt to determine whether you want to find using the `slugs` field or the `_id` field by inspecting the supplied parameters.
|
41
|
-
|
42
|
-
* Mongoid Slug will perform a find based on `slugs` only if all arguments passed to `find` are of the type `String`.
|
43
|
-
* If your document uses `BSON::ObjectId` identifiers, and all arguments look like valid `BSON::ObjectId`, then Mongoid Slug will perform a find based on `_id`.
|
44
|
-
* If your document uses any other type of identifiers, and all arguments passed to `find` are of the same type, then Mongoid Slug will perform a find based on `_id`.
|
45
|
-
* If your document uses `String` identifiers and you want to be able find by slugs or ids, to get the correct behaviour, you should add a `slug_id_strategy` option to your `_id` field definition. This option should return something that responds to `call` (a callable) and takes one string argument, e.g. a lambda. This callable must return true if the string looks like one of your ids.
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
Book.fields['_id'].type
|
49
|
-
=> String
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
include Mongoid::
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
post = Post.find '
|
68
|
-
=> ...
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
rake
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
class
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
end
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
By
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
Mongoid
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
1
|
+
Mongoid Slug
|
2
|
+
============
|
3
|
+
|
4
|
+
Mongoid Slug generates a URL slug or permalink based on one or more fields in a Mongoid model.
|
5
|
+
It sits idly on top of [stringex](https://github.com/rsl/stringex), supporting non-Latin characters.
|
6
|
+
|
7
|
+
[![Build Status](https://github.com/mongoid/mongoid-slug/actions/workflows/test.yml/badge.svg?query=branch%3Amaster)](https://github.com/mongoid/mongoid-slug/actions/workflows/test.ym?query=branch%3Amaster)
|
8
|
+
[![Gem Version](https://badge.fury.io/rb/mongoid-slug.svg)](http://badge.fury.io/rb/mongoid-slug)
|
9
|
+
[![Code Climate](https://codeclimate.com/github/mongoid/mongoid-slug.svg)](https://codeclimate.com/github/mongoid/mongoid-slug)
|
10
|
+
|
11
|
+
### Installation
|
12
|
+
|
13
|
+
Add to your Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'mongoid-slug'
|
17
|
+
```
|
18
|
+
|
19
|
+
### Usage
|
20
|
+
|
21
|
+
### Set Up a Slug
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class Book
|
25
|
+
include Mongoid::Document
|
26
|
+
include Mongoid::Slug
|
27
|
+
|
28
|
+
field :title
|
29
|
+
slug :title
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
### Find a Document by its Slug
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# GET /books/a-thousand-plateaus
|
37
|
+
book = Book.find params[:book_id]
|
38
|
+
```
|
39
|
+
|
40
|
+
Mongoid Slug will attempt to determine whether you want to find using the `slugs` field or the `_id` field by inspecting the supplied parameters.
|
41
|
+
|
42
|
+
* Mongoid Slug will perform a find based on `slugs` only if all arguments passed to `find` are of the type `String`.
|
43
|
+
* If your document uses `BSON::ObjectId` identifiers, and all arguments look like valid `BSON::ObjectId`, then Mongoid Slug will perform a find based on `_id`.
|
44
|
+
* If your document uses any other type of identifiers, and all arguments passed to `find` are of the same type, then Mongoid Slug will perform a find based on `_id`.
|
45
|
+
* If your document uses `String` identifiers and you want to be able find by slugs or ids, to get the correct behaviour, you should add a `slug_id_strategy` option to your `_id` field definition. This option should return something that responds to `call` (a callable) and takes one string argument, e.g. a lambda. This callable must return true if the string looks like one of your ids.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
Book.fields['_id'].type
|
49
|
+
=> String
|
50
|
+
|
51
|
+
book = Book.find 'a-thousand-plateaus' # Finds by slugs
|
52
|
+
=> ...
|
53
|
+
|
54
|
+
class Post
|
55
|
+
include Mongoid::Document
|
56
|
+
include Mongoid::Slug
|
57
|
+
|
58
|
+
field :_id, type: String, slug_id_strategy: lambda { |id| id.start_with?('...') }
|
59
|
+
|
60
|
+
field :name
|
61
|
+
slug :name, history: true
|
62
|
+
end
|
63
|
+
|
64
|
+
Post.fields['_id'].type
|
65
|
+
=> String
|
66
|
+
|
67
|
+
post = Post.find 'a-thousand-plateaus' # Finds by slugs
|
68
|
+
=> ...
|
69
|
+
|
70
|
+
post = Post.find '50b1386a0482939864000001' # Finds by bson ids
|
71
|
+
=> ...
|
72
|
+
```
|
73
|
+
[Examine slug.rb](lib/mongoid/slug.rb) for all available options.
|
74
|
+
|
75
|
+
### Updating Existing Records
|
76
|
+
|
77
|
+
To set slugs for existing records run following rake task:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
rake mongoid_slug:set
|
81
|
+
```
|
82
|
+
|
83
|
+
You can pass model names as an option for which you want to set slugs:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
rake mongoid_slug:set[Model1,Model2]
|
87
|
+
```
|
88
|
+
|
89
|
+
### Nil Slugs
|
90
|
+
|
91
|
+
Empty slugs are possible and generate a `nil` value for the `_slugs` field. In the `Post` example above, a blank post `name` will cause the document record not to contain a `_slugs` field in the database. The default `_slugs` index is `sparse`, allowing that. If you wish to change this behavior add a custom `validates_presence_of :_slugs` validator to the document or change the database index to `sparse: false`.
|
92
|
+
|
93
|
+
### Custom Slug Generation
|
94
|
+
|
95
|
+
By default Mongoid Slug generates slugs with stringex. If this is not desired you can define your own slug generator.
|
96
|
+
|
97
|
+
There are two ways to define slug generator.
|
98
|
+
|
99
|
+
#### Globally
|
100
|
+
|
101
|
+
Configure a block in `config/initializers/mongoid_slug.rb` as follows:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
Mongoid::Slug.configure do |c|
|
105
|
+
# create a block that takes the current object as an argument and return the slug
|
106
|
+
c.slug = proc { |cur_obj|
|
107
|
+
cur_object.slug_builder.to_url
|
108
|
+
}
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
#### On Model
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class Caption
|
116
|
+
include Mongoid::Document
|
117
|
+
include Mongoid::Slug
|
118
|
+
|
119
|
+
# create a block that takes the current object as an argument and returns the slug
|
120
|
+
slug do |cur_object|
|
121
|
+
cur_object.slug_builder.to_url
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
The `to_url` method comes from [stringex](https://github.com/rsl/stringex).
|
127
|
+
|
128
|
+
You can define a slug builder globally and/or override it per model.
|
129
|
+
|
130
|
+
### Scoping
|
131
|
+
|
132
|
+
To scope a slug by a reference association, pass `:scope`:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
class Company
|
136
|
+
include Mongoid::Document
|
137
|
+
|
138
|
+
references_many :employees
|
139
|
+
end
|
140
|
+
|
141
|
+
class Employee
|
142
|
+
include Mongoid::Document
|
143
|
+
include Mongoid::Slug
|
144
|
+
|
145
|
+
field :name
|
146
|
+
referenced_in :company
|
147
|
+
|
148
|
+
slug :name, scope: :company
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
In this example, if you create an employee without associating it with any company, the scope will fall back to the root employees collection.
|
153
|
+
|
154
|
+
Currently, if you have an irregular association name, you **must** specify the `:inverse_of` option on the other side of the assocation.
|
155
|
+
|
156
|
+
Embedded objects are automatically scoped by their parent.
|
157
|
+
|
158
|
+
Note that the unique index on the `Employee` collection in this example is derived from the `scope` value and is `{ _slugs: 1, company_id: 1}`. Therefore `:company` must be `referenced_in` above the definition of `slug` or it will not be able to resolve the association and mistakenly create a `{ _slugs: 1, company: 1}` index. An alternative is to scope to the field itself as follows:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
class Employee
|
162
|
+
include Mongoid::Document
|
163
|
+
include Mongoid::Slug
|
164
|
+
|
165
|
+
field :name
|
166
|
+
field :company_id
|
167
|
+
|
168
|
+
slug :name, scope: :company_id
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
### Limit Slug Length
|
173
|
+
|
174
|
+
MongoDB has a default limit around 1KB to the size of the index keys and will raise error 17280, `key too large to index` when trying to create a record that causes an index key to exceed that limit. By default slugs are of the form `text[-number]` and the text portion is limited in size to `Mongoid::Slug::MONGO_INDEX_KEY_LIMIT_BYTES - 32` bytes. You can change this limit with `max_length` or set it to `nil` if you're running MongoDB with [failIndexKeyTooLong](https://docs.mongodb.org/manual/reference/parameters/#param.failIndexKeyTooLong) set to `false`.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
class Company
|
178
|
+
include Mongoid::Document
|
179
|
+
include Mongoid::Slug
|
180
|
+
|
181
|
+
field :name
|
182
|
+
|
183
|
+
slug :name, max_length: 24
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
187
|
+
### Optionally Find and Create Slugs per Model Type
|
188
|
+
|
189
|
+
By default when using STI, the scope will be around the super-class.
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
class Book
|
193
|
+
include Mongoid::Document
|
194
|
+
include Mongoid::Slug
|
195
|
+
field :title
|
196
|
+
|
197
|
+
slug :title, history: true
|
198
|
+
embeds_many :subjects
|
199
|
+
has_many :authors
|
200
|
+
end
|
201
|
+
|
202
|
+
class ComicBook < Book
|
203
|
+
end
|
204
|
+
|
205
|
+
book = Book.create(title: 'Anti Oedipus')
|
206
|
+
comic_book = ComicBook.create(title: 'Anti Oedipus')
|
207
|
+
comic_book.slugs.should_not eql(book.slugs)
|
208
|
+
```
|
209
|
+
|
210
|
+
If you want the scope to be around the subclass, then set the option `by_model_type: true`.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
class Book
|
214
|
+
include Mongoid::Document
|
215
|
+
include Mongoid::Slug
|
216
|
+
field :title
|
217
|
+
|
218
|
+
slug :title, history: true, by_model_type: true
|
219
|
+
embeds_many :subjects
|
220
|
+
has_many :authors
|
221
|
+
end
|
222
|
+
|
223
|
+
class ComicBook < Book
|
224
|
+
end
|
225
|
+
|
226
|
+
book = Book.create(title: 'Anti Oedipus')
|
227
|
+
comic_book = ComicBook.create(title: 'Anti Oedipus')
|
228
|
+
comic_book.slugs.should eql(book.slugs)
|
229
|
+
```
|
230
|
+
|
231
|
+
### History
|
232
|
+
|
233
|
+
Enable slug history tracking by setting `history: true`.
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
class Page
|
237
|
+
include Mongoid::Document
|
238
|
+
include Mongoid::Slug
|
239
|
+
|
240
|
+
field :title
|
241
|
+
|
242
|
+
slug :title, history: true
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
The document will then be returned for any of the saved slugs:
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
page = Page.new title: "Home"
|
250
|
+
page.save
|
251
|
+
page.update_attributes title: "Welcome"
|
252
|
+
|
253
|
+
Page.find("welcome") == Page.find("home") # => true
|
254
|
+
```
|
255
|
+
|
256
|
+
### Reserved Slugs
|
257
|
+
|
258
|
+
Pass words you do not want to be slugged using the `reserve` option:
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
class Friend
|
262
|
+
include Mongoid::Document
|
263
|
+
|
264
|
+
field :name
|
265
|
+
slug :name, reserve: ['admin', 'root']
|
266
|
+
end
|
267
|
+
|
268
|
+
friend = Friend.create name: 'admin'
|
269
|
+
Friend.find('admin') # => nil
|
270
|
+
friend.slug # => 'admin-1'
|
271
|
+
```
|
272
|
+
|
273
|
+
When reserved words are not specified, the words 'new' and 'edit' are considered reserved by default.
|
274
|
+
Specifying an array of custom reserved words will overwrite these defaults.
|
275
|
+
|
276
|
+
### Localize Slugs
|
277
|
+
|
278
|
+
The slugs can be localized. This feature is built upon Mongoid localized fields,
|
279
|
+
so fallbacks and localization works as documented in the Mongoid manual.
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
class PageSlugLocalize
|
283
|
+
include Mongoid::Document
|
284
|
+
include Mongoid::Slug
|
285
|
+
|
286
|
+
field :title, localize: true
|
287
|
+
slug :title, localize: true
|
288
|
+
end
|
289
|
+
```
|
290
|
+
|
291
|
+
By specifying `localize: true`, the slug index will be created on the
|
292
|
+
[I18n.default_locale](http://guides.rubyonrails.org/i18n.html#the-public-i18n-api) field only.
|
293
|
+
For example, if `I18n.default_locale` is `:en`, the index will be generated as follows:
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
slug :title, localize: true
|
297
|
+
|
298
|
+
# The following indexes is auto-generated:
|
299
|
+
index({ '_slugs.en' => 1 }, { unique: true, sparse: true })
|
300
|
+
```
|
301
|
+
|
302
|
+
If you are supporting multiple locales, you may specify the list of locales on which
|
303
|
+
to create indexes as an `Array`.
|
304
|
+
|
305
|
+
```ruby
|
306
|
+
slug :title, localize: [:fr, :es, :de]
|
307
|
+
|
308
|
+
# The following indexes are auto-generated:
|
309
|
+
index({ '_slugs.fr' => 1 }, { unique: true, sparse: true })
|
310
|
+
index({ '_slugs.es' => 1 }, { unique: true, sparse: true })
|
311
|
+
index({ '_slugs.de' => 1 }, { unique: true, sparse: true })
|
312
|
+
```
|
313
|
+
|
314
|
+
### Custom Find Strategies
|
315
|
+
|
316
|
+
By default find will search for the document by the id field if the provided id looks like a `BSON::ObjectId`, and it will otherwise find by the _slugs field. However, custom strategies can ovveride the default behavior, like e.g:
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
module Mongoid::Slug::UuidIdStrategy
|
320
|
+
def self.call id
|
321
|
+
id =~ /\A([0-9a-fA-F]){8}-(([0-9a-fA-F]){4}-){3}([0-9a-fA-F]){12}\z/
|
322
|
+
end
|
323
|
+
end
|
324
|
+
```
|
325
|
+
|
326
|
+
Use a custom strategy by adding the `slug_id_strategy` annotation to the `_id` field:
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
class Entity
|
330
|
+
include Mongoid::Document
|
331
|
+
include Mongoid::Slug
|
332
|
+
|
333
|
+
field :_id, type: String, slug_id_strategy: UuidIdStrategy
|
334
|
+
|
335
|
+
field :user_edited_variation
|
336
|
+
slug :user_edited_variation, history: true
|
337
|
+
end
|
338
|
+
```
|
339
|
+
|
340
|
+
### Adhoc Checking Whether a Slug is Unique
|
341
|
+
|
342
|
+
Lets say you want to have a auto-suggest function on your GUI that could provide a preview of what the url or slug could be before the form to create the record was submitted.
|
343
|
+
|
344
|
+
You can use the UniqueSlug class in your server side code to do this, e.g.
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
title = params[:title]
|
348
|
+
unique = Mongoid::Slug::UniqueSlug.new(Book.new).find_unique(title)
|
349
|
+
...
|
350
|
+
# return some representation of unique
|
351
|
+
```
|
352
|
+
|
353
|
+
Contributing
|
354
|
+
------------
|
355
|
+
|
356
|
+
Mongoid-slug is work of [many of contributors](https://github.com/mongoid/mongoid-slug/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/mongoid/mongoid-slug/pulls), [propose features, ask questions and discuss issues](https://github.com/mongoid/mongoid-slug/issues). See [CONTRIBUTING](CONTRIBUTING.md) for details.
|
357
|
+
|
358
|
+
Copyright & License
|
359
|
+
-------------------
|
360
|
+
|
361
|
+
Copyright (c) 2010-2017 Hakan Ensari & Contributors, see [LICENSE](LICENSE) for details.
|