mongoid-slug 6.0.0 → 7.0.0
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 +392 -336
- data/lib/mongoid/slug/criteria.rb +111 -107
- data/lib/mongoid/slug/{index.rb → index_builder.rb} +69 -45
- data/lib/mongoid/slug/railtie.rb +11 -9
- data/lib/mongoid/slug/slug_id_strategy.rb +5 -3
- data/lib/mongoid/slug/unique_slug.rb +172 -173
- data/lib/mongoid/slug/version.rb +7 -5
- data/lib/mongoid/slug.rb +333 -328
- data/lib/mongoid_slug.rb +4 -2
- data/lib/tasks/mongoid_slug.rake +17 -19
- metadata +13 -173
- data/spec/models/alias.rb +0 -6
- data/spec/models/article.rb +0 -9
- data/spec/models/artist.rb +0 -8
- data/spec/models/artwork.rb +0 -10
- data/spec/models/author.rb +0 -15
- data/spec/models/author_polymorphic.rb +0 -15
- data/spec/models/book.rb +0 -12
- data/spec/models/book_polymorphic.rb +0 -12
- data/spec/models/caption.rb +0 -17
- data/spec/models/entity.rb +0 -11
- data/spec/models/friend.rb +0 -7
- data/spec/models/incorrect_slug_persistence.rb +0 -9
- data/spec/models/integer_id.rb +0 -9
- data/spec/models/magazine.rb +0 -7
- data/spec/models/page.rb +0 -9
- data/spec/models/page_localize.rb +0 -9
- data/spec/models/page_slug_localized.rb +0 -9
- data/spec/models/page_slug_localized_custom.rb +0 -10
- data/spec/models/page_slug_localized_history.rb +0 -9
- data/spec/models/partner.rb +0 -7
- data/spec/models/person.rb +0 -12
- data/spec/models/relationship.rb +0 -8
- data/spec/models/string_id.rb +0 -9
- data/spec/models/subject.rb +0 -7
- data/spec/models/without_slug.rb +0 -5
- data/spec/mongoid/criteria_spec.rb +0 -207
- data/spec/mongoid/index_spec.rb +0 -33
- data/spec/mongoid/slug_spec.rb +0 -1169
- data/spec/shared/indexes.rb +0 -41
- data/spec/spec_helper.rb +0 -61
- data/spec/tasks/mongoid_slug_rake_spec.rb +0 -73
data/README.md
CHANGED
@@ -1,336 +1,392 @@
|
|
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
|
-
###
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
```
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
[
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
include Mongoid::
|
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
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
class
|
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
|
-
|
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
|
-
|
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
|
+
### Version Support
|
12
|
+
|
13
|
+
Mongoid Slug 7.x requires at least Mongoid 7.0.0 and Ruby 2.7.0. For earlier Mongoid and Ruby version support, please use an earlier version of Mongoid Slug.
|
14
|
+
|
15
|
+
Mongoid Slug is compatible with all MongoDB versions which Mongoid supports, however, please see "Slug Max Length" section below for MongoDB 4.0 and earlier.
|
16
|
+
|
17
|
+
### Installation
|
18
|
+
|
19
|
+
Add to your Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'mongoid-slug'
|
23
|
+
```
|
24
|
+
|
25
|
+
### Usage
|
26
|
+
|
27
|
+
### Set Up a Slug
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
class Book
|
31
|
+
include Mongoid::Document
|
32
|
+
include Mongoid::Slug
|
33
|
+
|
34
|
+
field :title
|
35
|
+
slug :title
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
### Find a Document by its Slug
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# GET /books/a-thousand-plateaus
|
43
|
+
book = Book.find params[:book_id]
|
44
|
+
```
|
45
|
+
|
46
|
+
Mongoid Slug will attempt to determine whether you want to find using the `slugs` field or the `_id` field by inspecting the supplied parameters.
|
47
|
+
|
48
|
+
* Mongoid Slug will perform a find based on `slugs` only if all arguments passed to `find` are of the type `String`.
|
49
|
+
* 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`.
|
50
|
+
* 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`.
|
51
|
+
* 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.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Book.fields['_id'].type
|
55
|
+
=> String
|
56
|
+
|
57
|
+
book = Book.find 'a-thousand-plateaus' # Finds by slugs
|
58
|
+
=> ...
|
59
|
+
|
60
|
+
class Post
|
61
|
+
include Mongoid::Document
|
62
|
+
include Mongoid::Slug
|
63
|
+
|
64
|
+
field :_id, type: String, slug_id_strategy: lambda { |id| id.start_with?('...') }
|
65
|
+
|
66
|
+
field :name
|
67
|
+
slug :name, history: true
|
68
|
+
end
|
69
|
+
|
70
|
+
Post.fields['_id'].type
|
71
|
+
=> String
|
72
|
+
|
73
|
+
post = Post.find 'a-thousand-plateaus' # Finds by slugs
|
74
|
+
=> ...
|
75
|
+
|
76
|
+
post = Post.find '50b1386a0482939864000001' # Finds by bson ids
|
77
|
+
=> ...
|
78
|
+
```
|
79
|
+
|
80
|
+
[Examine slug.rb](lib/mongoid/slug.rb) for all available options.
|
81
|
+
|
82
|
+
### Updating Existing Records
|
83
|
+
|
84
|
+
To set slugs for existing records run following rake task:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
rake mongoid_slug:set
|
88
|
+
```
|
89
|
+
|
90
|
+
You can pass model names as an option for which you want to set slugs:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
rake mongoid_slug:set[Model1,Model2]
|
94
|
+
```
|
95
|
+
|
96
|
+
### Nil Slugs
|
97
|
+
|
98
|
+
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`.
|
99
|
+
|
100
|
+
### Custom Slug Generation
|
101
|
+
|
102
|
+
By default Mongoid Slug generates slugs with stringex. If this is not desired you can define your own slug generator.
|
103
|
+
|
104
|
+
There are two ways to define slug generator.
|
105
|
+
|
106
|
+
#### Globally
|
107
|
+
|
108
|
+
Configure a block in `config/initializers/mongoid_slug.rb` as follows:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
Mongoid::Slug.configure do |c|
|
112
|
+
# create a block that takes the current object as an argument and return the slug
|
113
|
+
c.slug = proc { |cur_obj|
|
114
|
+
cur_object.slug_builder.to_url
|
115
|
+
}
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
#### On Model
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
class Caption
|
123
|
+
include Mongoid::Document
|
124
|
+
include Mongoid::Slug
|
125
|
+
|
126
|
+
# create a block that takes the current object as an argument and returns the slug
|
127
|
+
slug do |cur_object|
|
128
|
+
cur_object.slug_builder.to_url
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
The `to_url` method comes from [stringex](https://github.com/rsl/stringex).
|
134
|
+
|
135
|
+
You can define a slug builder globally and/or override it per model.
|
136
|
+
|
137
|
+
### Indexing
|
138
|
+
|
139
|
+
By default, Mongoid Slug will automatically generate an index for the slug, which will be created when you run `rake db:create_indexes`. This index will take into account scoping and other options described below.
|
140
|
+
|
141
|
+
To skip this index generation, you may set `index: false` as follows:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
class Employee
|
145
|
+
include Mongoid::Document
|
146
|
+
include Mongoid::Slug
|
147
|
+
|
148
|
+
field :name
|
149
|
+
|
150
|
+
slug :name, index: :false
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
### Scoping
|
155
|
+
|
156
|
+
To scope a slug by a reference association, pass `:scope`:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
class Company
|
160
|
+
include Mongoid::Document
|
161
|
+
|
162
|
+
references_many :employees
|
163
|
+
end
|
164
|
+
|
165
|
+
class Employee
|
166
|
+
include Mongoid::Document
|
167
|
+
include Mongoid::Slug
|
168
|
+
|
169
|
+
field :name
|
170
|
+
referenced_in :company
|
171
|
+
|
172
|
+
slug :name, scope: :company
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
In this example, if you create an employee without associating it with any company, the scope will fall back to the root employees collection.
|
177
|
+
|
178
|
+
Currently, if you have an irregular association name, you **must** specify the `:inverse_of` option on the other side of the assocation.
|
179
|
+
|
180
|
+
Embedded objects are automatically scoped by their parent.
|
181
|
+
|
182
|
+
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:
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
class Employee
|
186
|
+
include Mongoid::Document
|
187
|
+
include Mongoid::Slug
|
188
|
+
|
189
|
+
field :name
|
190
|
+
field :company_id
|
191
|
+
|
192
|
+
slug :name, scope: :company_id
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
### Slug Max Length
|
197
|
+
|
198
|
+
MongoDB [featureCompatibilityVersion](https://docs.mongodb.com/manual/reference/command/setFeatureCompatibilityVersion/#std-label-view-fcv)
|
199
|
+
"4.0" and earlier applies an [Index Key Limit](https://docs.mongodb.com/manual/reference/limits/#mongodb-limit-Index-Key-Limit)
|
200
|
+
which limits the total size of an index entry to around 1KB and will raise error,
|
201
|
+
`17280 - key too large to index` when trying to create a record that causes an index key to exceed that limit.
|
202
|
+
By default slugs are of the form `text[-number]` and the text portion is limited in size
|
203
|
+
to `Mongoid::Slug::MONGO_INDEX_KEY_LIMIT_BYTES - 32` bytes.
|
204
|
+
You can change this limit with `max_length` or set it to `nil` if you're running MongoDB
|
205
|
+
with [failIndexKeyTooLong](https://docs.mongodb.org/manual/reference/parameters/#param.failIndexKeyTooLong) set to `false`.
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
class Company
|
209
|
+
include Mongoid::Document
|
210
|
+
include Mongoid::Slug
|
211
|
+
|
212
|
+
field :name
|
213
|
+
|
214
|
+
slug :name, max_length: 24
|
215
|
+
end
|
216
|
+
```
|
217
|
+
|
218
|
+
### Optionally Find and Create Slugs per Model Type
|
219
|
+
|
220
|
+
By default when using STI, the scope will be around the super-class.
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
class Book
|
224
|
+
include Mongoid::Document
|
225
|
+
include Mongoid::Slug
|
226
|
+
field :title
|
227
|
+
|
228
|
+
slug :title, history: true
|
229
|
+
embeds_many :subjects
|
230
|
+
has_many :authors
|
231
|
+
end
|
232
|
+
|
233
|
+
class ComicBook < Book
|
234
|
+
end
|
235
|
+
|
236
|
+
book = Book.create(title: 'Anti Oedipus')
|
237
|
+
comic_book = ComicBook.create(title: 'Anti Oedipus')
|
238
|
+
comic_book.slugs.should_not eql(book.slugs)
|
239
|
+
```
|
240
|
+
|
241
|
+
If you want the scope to be around the subclass, then set the option `by_model_type: true`.
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
class Book
|
245
|
+
include Mongoid::Document
|
246
|
+
include Mongoid::Slug
|
247
|
+
field :title
|
248
|
+
|
249
|
+
slug :title, history: true, by_model_type: true
|
250
|
+
embeds_many :subjects
|
251
|
+
has_many :authors
|
252
|
+
end
|
253
|
+
|
254
|
+
class ComicBook < Book
|
255
|
+
end
|
256
|
+
|
257
|
+
book = Book.create(title: 'Anti Oedipus')
|
258
|
+
comic_book = ComicBook.create(title: 'Anti Oedipus')
|
259
|
+
comic_book.slugs.should eql(book.slugs)
|
260
|
+
```
|
261
|
+
|
262
|
+
### History
|
263
|
+
|
264
|
+
Enable slug history tracking by setting `history: true`.
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
class Page
|
268
|
+
include Mongoid::Document
|
269
|
+
include Mongoid::Slug
|
270
|
+
|
271
|
+
field :title
|
272
|
+
|
273
|
+
slug :title, history: true
|
274
|
+
end
|
275
|
+
```
|
276
|
+
|
277
|
+
The document will then be returned for any of the saved slugs:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
page = Page.new title: "Home"
|
281
|
+
page.save
|
282
|
+
page.update_attributes title: "Welcome"
|
283
|
+
|
284
|
+
Page.find("welcome") == Page.find("home") # => true
|
285
|
+
```
|
286
|
+
|
287
|
+
### Reserved Slugs
|
288
|
+
|
289
|
+
Pass words you do not want to be slugged using the `reserve` option:
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
class Friend
|
293
|
+
include Mongoid::Document
|
294
|
+
|
295
|
+
field :name
|
296
|
+
slug :name, reserve: ['admin', 'root']
|
297
|
+
end
|
298
|
+
|
299
|
+
friend = Friend.create name: 'admin'
|
300
|
+
Friend.find('admin') # => nil
|
301
|
+
friend.slug # => 'admin-1'
|
302
|
+
```
|
303
|
+
|
304
|
+
When reserved words are not specified, the words 'new' and 'edit' are considered reserved by default.
|
305
|
+
Specifying an array of custom reserved words will overwrite these defaults.
|
306
|
+
|
307
|
+
### Localize Slugs
|
308
|
+
|
309
|
+
The slugs can be localized. This feature is built upon Mongoid localized fields,
|
310
|
+
so fallbacks and localization works as documented in the Mongoid manual.
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
class PageSlugLocalize
|
314
|
+
include Mongoid::Document
|
315
|
+
include Mongoid::Slug
|
316
|
+
|
317
|
+
field :title, localize: true
|
318
|
+
slug :title, localize: true
|
319
|
+
end
|
320
|
+
```
|
321
|
+
|
322
|
+
By specifying `localize: true`, the slug index will be created on the
|
323
|
+
[I18n.default_locale](http://guides.rubyonrails.org/i18n.html#the-public-i18n-api) field only.
|
324
|
+
For example, if `I18n.default_locale` is `:en`, the index will be generated as follows:
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
slug :title, localize: true
|
328
|
+
|
329
|
+
# The following index is auto-generated:
|
330
|
+
index({ '_slugs.en' => 1 }, { unique: true, sparse: true })
|
331
|
+
```
|
332
|
+
|
333
|
+
If you are supporting multiple locales, you may specify the list of locales on which
|
334
|
+
to create indexes as an `Array`.
|
335
|
+
|
336
|
+
```ruby
|
337
|
+
slug :title, localize: [:fr, :es, :de]
|
338
|
+
|
339
|
+
# The following indexes are auto-generated:
|
340
|
+
index({ '_slugs.fr' => 1 }, { unique: true, sparse: true })
|
341
|
+
index({ '_slugs.es' => 1 }, { unique: true, sparse: true })
|
342
|
+
index({ '_slugs.de' => 1 }, { unique: true, sparse: true })
|
343
|
+
```
|
344
|
+
|
345
|
+
### Custom Find Strategies
|
346
|
+
|
347
|
+
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:
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
module Mongoid::Slug::UuidIdStrategy
|
351
|
+
def self.call id
|
352
|
+
id =~ /\A([0-9a-fA-F]){8}-(([0-9a-fA-F]){4}-){3}([0-9a-fA-F]){12}\z/
|
353
|
+
end
|
354
|
+
end
|
355
|
+
```
|
356
|
+
|
357
|
+
Use a custom strategy by adding the `slug_id_strategy` annotation to the `_id` field:
|
358
|
+
|
359
|
+
```ruby
|
360
|
+
class Entity
|
361
|
+
include Mongoid::Document
|
362
|
+
include Mongoid::Slug
|
363
|
+
|
364
|
+
field :_id, type: String, slug_id_strategy: UuidIdStrategy
|
365
|
+
|
366
|
+
field :user_edited_variation
|
367
|
+
slug :user_edited_variation, history: true
|
368
|
+
end
|
369
|
+
```
|
370
|
+
|
371
|
+
### Adhoc Checking Whether a Slug is Unique
|
372
|
+
|
373
|
+
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.
|
374
|
+
|
375
|
+
You can use the UniqueSlug class in your server side code to do this, e.g.
|
376
|
+
|
377
|
+
```ruby
|
378
|
+
title = params[:title]
|
379
|
+
unique = Mongoid::Slug::UniqueSlug.new(Book.new).find_unique(title)
|
380
|
+
...
|
381
|
+
# return some representation of unique
|
382
|
+
```
|
383
|
+
|
384
|
+
Contributing
|
385
|
+
------------
|
386
|
+
|
387
|
+
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.
|
388
|
+
|
389
|
+
Copyright & License
|
390
|
+
-------------------
|
391
|
+
|
392
|
+
Copyright (c) 2010-2017 Hakan Ensari & Contributors, see [LICENSE](LICENSE) for details.
|