opaque_id 1.7.0 → 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/docs/usage.md DELETED
@@ -1,421 +0,0 @@
1
- ---
2
- layout: default
3
- title: Usage
4
- nav_order: 4
5
- description: "Complete usage guide with standalone and ActiveRecord examples"
6
- permalink: /usage/
7
- ---
8
-
9
- # Usage
10
-
11
- This guide covers all usage patterns for OpaqueId, from basic standalone generation to advanced ActiveRecord integration.
12
-
13
- - TOC
14
- {:toc}
15
-
16
- ## Standalone ID Generation
17
-
18
- OpaqueId can be used independently of ActiveRecord for generating secure, random IDs.
19
-
20
- ### Basic Usage
21
-
22
- ```ruby
23
- # Generate a default opaque ID (18 characters, slug-like)
24
- id = OpaqueId.generate
25
- # => "izkpm55j334u8x9y2a"
26
-
27
- # Generate multiple IDs
28
- ids = 5.times.map { OpaqueId.generate }
29
- # => ["izkpm55j334u8x9y2a", "k8jh2mn9pl3qr7st1v", ...]
30
- ```
31
-
32
- ### Custom Parameters
33
-
34
- ```ruby
35
- # Custom length
36
- id = OpaqueId.generate(size: 10)
37
- # => "izkpm55j334u"
38
-
39
- # Custom alphabet
40
- id = OpaqueId.generate(alphabet: OpaqueId::STANDARD_ALPHABET)
41
- # => "V1StGXR8_Z5jdHi6B-myT"
42
-
43
- # Both custom length and alphabet
44
- id = OpaqueId.generate(size: 15, alphabet: OpaqueId::STANDARD_ALPHABET)
45
- # => "V1StGXR8_Z5jdHi6B"
46
- ```
47
-
48
- ### Built-in Alphabets
49
-
50
- ```ruby
51
- # Slug-like alphabet (default) - 0-9, a-z
52
- id = OpaqueId.generate(alphabet: OpaqueId::SLUG_LIKE_ALPHABET)
53
- # => "izkpm55j334u8x9y2a"
54
-
55
- # Alphanumeric alphabet - A-Z, a-z, 0-9
56
- id = OpaqueId.generate(alphabet: OpaqueId::ALPHANUMERIC_ALPHABET)
57
- # => "V1StGXR8Z5jdHi6BmyT"
58
-
59
- # Standard alphabet - A-Z, a-z, 0-9, -, _
60
- id = OpaqueId.generate(alphabet: OpaqueId::STANDARD_ALPHABET)
61
- # => "V1StGXR8_Z5jdHi6B-myT"
62
- ```
63
-
64
- ### Custom Alphabets
65
-
66
- ```ruby
67
- # Numeric only
68
- numeric_alphabet = "0123456789"
69
- id = OpaqueId.generate(size: 8, alphabet: numeric_alphabet)
70
- # => "12345678"
71
-
72
- # Hexadecimal
73
- hex_alphabet = "0123456789abcdef"
74
- id = OpaqueId.generate(size: 16, alphabet: hex_alphabet)
75
- # => "a1b2c3d4e5f67890"
76
-
77
- # URL-safe characters
78
- url_safe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
79
- id = OpaqueId.generate(size: 12, alphabet: url_safe)
80
- # => "izkpm55j334u8x"
81
- ```
82
-
83
- ## ActiveRecord Integration
84
-
85
- OpaqueId provides seamless integration with ActiveRecord models through the `OpaqueId::Model` concern.
86
-
87
- ### Basic Model Setup
88
-
89
- ```ruby
90
- class User < ApplicationRecord
91
- include OpaqueId::Model
92
- end
93
- ```
94
-
95
- ### Automatic ID Generation
96
-
97
- ```ruby
98
- # Create a new user - opaque_id is automatically generated
99
- user = User.create!(name: "John Doe", email: "john@example.com")
100
- puts user.opaque_id
101
- # => "izkpm55j334u8x9y2a"
102
-
103
- # The ID is generated before the record is saved
104
- user = User.new(name: "Jane Smith")
105
- puts user.opaque_id
106
- # => nil (not generated yet)
107
-
108
- user.save!
109
- puts user.opaque_id
110
- # => "k8jh2mn9pl3qr7st1va" (generated on save)
111
- ```
112
-
113
- ### Finder Methods
114
-
115
- ```ruby
116
- # Find by opaque_id (returns nil if not found)
117
- user = User.find_by_opaque_id("izkpm55j334u8x9y2a")
118
-
119
- # Find by opaque_id (raises exception if not found)
120
- user = User.find_by_opaque_id!("izkpm55j334u8x9y2a")
121
- # => ActiveRecord::RecordNotFound if not found
122
-
123
- # Use in scopes
124
- class User < ApplicationRecord
125
- include OpaqueId::Model
126
-
127
- scope :by_opaque_id, ->(id) { where(opaque_id: id) }
128
- end
129
-
130
- users = User.by_opaque_id("izkpm55j334u8x9y2a")
131
- ```
132
-
133
- ### Custom Column Names
134
-
135
- ```ruby
136
- class User < ApplicationRecord
137
- include OpaqueId::Model
138
-
139
- # Use a different column name
140
- self.opaque_id_column = :public_id
141
- end
142
-
143
- # Now the methods use the custom column name
144
- user = User.create!(name: "John Doe")
145
- puts user.public_id
146
- # => "izkpm55j334u8x9y2a"
147
-
148
- user = User.find_by_public_id("izkpm55j334u8x9y2a")
149
- ```
150
-
151
- ## Rails Generator
152
-
153
- The Rails generator provides a convenient way to set up OpaqueId for your models.
154
-
155
- ### Basic Generator Usage
156
-
157
- ```bash
158
- # Generate setup for a User model
159
- rails generate opaque_id:install User
160
- ```
161
-
162
- This creates:
163
-
164
- - A migration to add the `opaque_id` column
165
- - A unique index on the `opaque_id` column
166
- - Includes the `OpaqueId::Model` concern in your model
167
-
168
- ### Custom Column Names
169
-
170
- ```bash
171
- # Use a custom column name
172
- rails generate opaque_id:install User --column-name=public_id
173
- ```
174
-
175
- This will:
176
-
177
- - Create a `public_id` column instead of `opaque_id`
178
- - Add `self.opaque_id_column = :public_id` to your model
179
-
180
- ### Multiple Models
181
-
182
- ```bash
183
- # Set up multiple models
184
- rails generate opaque_id:install User
185
- rails generate opaque_id:install Post --column-name=slug
186
- rails generate opaque_id:install Comment
187
- ```
188
-
189
- ## Real-World Examples
190
-
191
- ### E-commerce Application
192
-
193
- ```ruby
194
- class Order < ApplicationRecord
195
- include OpaqueId::Model
196
-
197
- # Use shorter IDs for orders
198
- self.opaque_id_length = 12
199
- self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
200
- end
201
-
202
- # Create an order
203
- order = Order.create!(user_id: 1, total: 99.99)
204
- puts order.opaque_id
205
- # => "izkpm55j334u8x"
206
-
207
- # Use in URLs
208
- order_url(order.opaque_id)
209
- # => "/orders/V1StGXR8_Z5j"
210
- ```
211
-
212
- ### API Development
213
-
214
- ```ruby
215
- class ApiKey < ApplicationRecord
216
- include OpaqueId::Model
217
-
218
- # Use longer IDs for API keys
219
- self.opaque_id_length = 32
220
- self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
221
- end
222
-
223
- # Generate API key
224
- api_key = ApiKey.create!(user_id: 1, name: "Mobile App")
225
- puts api_key.opaque_id
226
- # => "V1StGXR8_Z5jdHi6B-myT1234567890"
227
-
228
- # Use in API requests
229
- # Authorization: Bearer V1StGXR8_Z5jdHi6B-myT1234567890
230
- ```
231
-
232
- ### Content Management
233
-
234
- ```ruby
235
- class Article < ApplicationRecord
236
- include OpaqueId::Model
237
-
238
- # Use URL-safe characters for slugs
239
- self.opaque_id_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
240
- self.opaque_id_length = 8
241
- end
242
-
243
- # Create an article
244
- article = Article.create!(title: "My Article", content: "Content here")
245
- puts article.opaque_id
246
- # => "V1StGXR8"
247
-
248
- # Use in URLs
249
- article_url(article.opaque_id)
250
- # => "/articles/V1StGXR8"
251
- ```
252
-
253
- ### User Management
254
-
255
- ```ruby
256
- class User < ApplicationRecord
257
- include OpaqueId::Model
258
-
259
- # Require letter start for user IDs
260
- self.opaque_id_require_letter_start = true
261
- end
262
-
263
- # Create a user
264
- user = User.create!(name: "John Doe", email: "john@example.com")
265
- puts user.opaque_id
266
- # => "izkpm55j334u8x9y2a" (starts with letter)
267
-
268
- # Use in user profiles
269
- user_url(user.opaque_id)
270
- # => "/users/V1StGXR8_Z5jdHi6B-myT"
271
- ```
272
-
273
- ## Advanced Usage Patterns
274
-
275
- ### Batch Operations
276
-
277
- ```ruby
278
- # Generate multiple IDs at once
279
- ids = 100.times.map { OpaqueId.generate }
280
- # => ["izkpm55j334u8x9y2a", "k8jh2mn9pl3qr7st1va", ...]
281
-
282
- # Use in bulk operations
283
- users_data = ids.map.with_index do |id, index|
284
- { opaque_id: id, name: "User #{index + 1}" }
285
- end
286
-
287
- User.insert_all(users_data)
288
- ```
289
-
290
- ### Conditional ID Generation
291
-
292
- ```ruby
293
- class User < ApplicationRecord
294
- include OpaqueId::Model
295
-
296
- private
297
-
298
- def set_opaque_id
299
- # Only generate ID if not already set
300
- return if opaque_id.present?
301
-
302
- # Custom generation logic
303
- self.opaque_id = generate_custom_id
304
- end
305
-
306
- def generate_custom_id
307
- # Generate ID with custom logic
308
- base_id = OpaqueId.generate(size: 15)
309
- "usr_#{base_id}"
310
- end
311
- end
312
- ```
313
-
314
- ### Error Handling
315
-
316
- ```ruby
317
- class User < ApplicationRecord
318
- include OpaqueId::Model
319
-
320
- # Handle generation failures
321
- rescue_from OpaqueId::GenerationError do |exception|
322
- Rails.logger.error "Failed to generate opaque ID: #{exception.message}"
323
- # Fallback to a different generation method
324
- self.opaque_id = generate_fallback_id
325
- end
326
-
327
- private
328
-
329
- def generate_fallback_id
330
- # Fallback generation method
331
- "fallback_#{SecureRandom.hex(10)}"
332
- end
333
- end
334
- ```
335
-
336
- ## Performance Considerations
337
-
338
- ### Batch Generation
339
-
340
- ```ruby
341
- # Efficient batch generation
342
- def generate_batch_ids(count, size: 21, alphabet: OpaqueId::ALPHANUMERIC_ALPHABET)
343
- count.times.map { OpaqueId.generate(size: size, alphabet: alphabet) }
344
- end
345
-
346
- # Generate 1000 IDs
347
- ids = generate_batch_ids(1000)
348
- ```
349
-
350
- ### Caching Generated IDs
351
-
352
- ```ruby
353
- class User < ApplicationRecord
354
- include OpaqueId::Model
355
-
356
- # Cache the generated ID
357
- def opaque_id
358
- @opaque_id ||= super
359
- end
360
- end
361
- ```
362
-
363
- ## Best Practices
364
-
365
- ### 1. Choose Appropriate Length
366
-
367
- ```ruby
368
- # Short IDs for public URLs
369
- self.opaque_id_length = 8
370
-
371
- # Medium IDs for general use
372
- self.opaque_id_length = 21
373
-
374
- # Long IDs for sensitive data
375
- self.opaque_id_length = 32
376
- ```
377
-
378
- ### 2. Select Suitable Alphabets
379
-
380
- ```ruby
381
- # URL-safe for public URLs
382
- self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
383
-
384
- # Fastest generation
385
- self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
386
-
387
- # Custom for specific needs
388
- self.opaque_id_alphabet = "0123456789ABCDEF"
389
- ```
390
-
391
- ### 3. Handle Collisions Gracefully
392
-
393
- ```ruby
394
- class User < ApplicationRecord
395
- include OpaqueId::Model
396
-
397
- # Increase retry attempts for high-volume applications
398
- self.opaque_id_max_retry = 10
399
- end
400
- ```
401
-
402
- ### 4. Use Appropriate Finder Methods
403
-
404
- ```ruby
405
- # Use find_by_opaque_id for optional lookups
406
- user = User.find_by_opaque_id(params[:id])
407
-
408
- # Use find_by_opaque_id! for required lookups
409
- user = User.find_by_opaque_id!(params[:id])
410
- ```
411
-
412
- ## Next Steps
413
-
414
- Now that you understand the usage patterns:
415
-
416
- 1. **Explore [Configuration](configuration.md)** for advanced setup
417
- 2. **Check out [Use Cases](use-cases.md)** for more real-world scenarios
418
- 3. **Review [Performance](performance.md)** for optimization tips
419
- 4. **Read [API Reference](api-reference.md)** for complete documentation
420
- 5. **Learn about [Alphabets](alphabets.md)** for custom character sets
421
- 6. **Understand [Algorithms](algorithms.md)** for technical details