encoded_id-rails 1.0.0.rc1 → 1.0.0.rc7

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +97 -18
  3. data/LICENSE.txt +1 -1
  4. data/README.md +81 -473
  5. data/context/encoded_id-rails.md +651 -0
  6. data/context/encoded_id.md +437 -0
  7. data/lib/encoded_id/rails/active_record_finders.rb +54 -0
  8. data/lib/encoded_id/rails/annotated_id.rb +14 -9
  9. data/lib/encoded_id/rails/annotated_id_parser.rb +9 -1
  10. data/lib/encoded_id/rails/coder.rb +55 -10
  11. data/lib/encoded_id/rails/composite_id_base.rb +39 -0
  12. data/lib/encoded_id/rails/configuration.rb +66 -10
  13. data/lib/encoded_id/rails/encoder_methods.rb +30 -7
  14. data/lib/encoded_id/rails/finder_methods.rb +11 -0
  15. data/lib/encoded_id/rails/model.rb +60 -7
  16. data/lib/encoded_id/rails/path_param.rb +8 -0
  17. data/lib/encoded_id/rails/persists.rb +55 -9
  18. data/lib/encoded_id/rails/query_methods.rb +21 -4
  19. data/lib/encoded_id/rails/railtie.rb +13 -0
  20. data/lib/encoded_id/rails/salt.rb +8 -0
  21. data/lib/encoded_id/rails/slugged_id.rb +14 -9
  22. data/lib/encoded_id/rails/slugged_id_parser.rb +9 -1
  23. data/lib/encoded_id/rails/slugged_path_param.rb +8 -0
  24. data/lib/encoded_id/rails.rb +11 -6
  25. data/lib/generators/encoded_id/rails/install_generator.rb +36 -2
  26. data/lib/generators/encoded_id/rails/templates/{encoded_id.rb → hashids_encoded_id.rb} +49 -5
  27. data/lib/generators/encoded_id/rails/templates/sqids_encoded_id.rb +116 -0
  28. metadata +16 -24
  29. data/.devcontainer/Dockerfile +0 -17
  30. data/.devcontainer/compose.yml +0 -10
  31. data/.devcontainer/devcontainer.json +0 -12
  32. data/.standard.yml +0 -3
  33. data/Appraisals +0 -9
  34. data/Gemfile +0 -24
  35. data/Rakefile +0 -20
  36. data/Steepfile +0 -4
  37. data/gemfiles/.bundle/config +0 -2
  38. data/gemfiles/rails_7.2.gemfile +0 -19
  39. data/gemfiles/rails_8.0.gemfile +0 -19
  40. data/lib/encoded_id/rails/version.rb +0 -7
  41. data/rbs_collection.yaml +0 -24
  42. data/sig/encoded_id/rails.rbs +0 -141
data/README.md CHANGED
@@ -1,533 +1,141 @@
1
- # EncodedId::Rails (`encoded_id-rails`)
1
+ # EncodedId and EncodedId::Rails
2
2
 
3
- `EncodedId::Rails` lets you turn numeric or hex **IDs into reversible and human friendly obfuscated strings**. The gem brings [EncodedId](https://github.com/stevegeek/encoded_id) to Rails and `ActiveRecord` models.
3
+ ![Coverage](badges/coverage_badge_total.svg)
4
+ ![RubyCritic](badges/rubycritic_badge_score.svg)
4
5
 
5
- You can use it in routes for example, to go from something like `/users/725` to `/users/bob-smith--usr_p5w9-z27j` with minimal effort.
6
+ `encoded_id` lets you encode numerical or hex IDs into obfuscated strings that can be used in URLs.
6
7
 
7
- ## Features
8
+ `encoded_id-rails` is a Rails integration that provides additional features for using `encoded_id` with ActiveRecord models.
8
9
 
9
- Under the hood it uses hashIds, but it offers more features.
10
+ It's one of the most, if not _the_ most, feature complete gem of its kind!
10
11
 
11
- - 🔄 encoded IDs are reversible (see [`encoded_id`](https://github.com/stevegeek/encoded_id))
12
- - 💅 supports slugged IDs (eg `my-cool-product-name--p5w9-z27j`) that are URL friendly (assuming your alphabet is too)
13
- - 🔖 supports annotated IDs to help identify the model the encoded ID belongs to (eg for a `User` the encoded ID might be `user_p5w9-z27j`)
14
- - 👓 encoded string can be split into groups of letters to improve human-readability (eg `abcd-efgh`)
15
- - 👥 supports multiple IDs encoded in one encoded string (eg imagine the encoded ID `7aq60zqw` might decode to two IDs `[78, 45]`)
16
- - 🔡 supports custom alphabets for the encoded string (at least 16 characters needed)
17
- - by default uses a variation of the Crockford reduced character set (https://www.crockford.com/base32.html)
18
- - easily confused characters (eg i and j, 0 and O, 1 and I etc) are mapped to counterpart characters, to
19
- help avoid common readability mistakes when reading/sharing
20
- - built-in profanity limitation
12
+ 👉 **Full documentation available at [encoded-id.onrender.com](https://encoded-id.onrender.com)**
21
13
 
22
- The gem provides:
14
+ ## Key Features
23
15
 
24
- - methods to mixin to ActiveRecord models which will allow you to encode and decode IDs, and find
25
- or query by encoded IDs
26
- - sensible defaults to allow you to get started out of the box
16
+ * 🔄 **Reversible** - Encoded IDs can be decoded back to the original values
17
+ * 👥 **Multiple IDs** - Encode multiple numeric IDs in one string
18
+ * 🚀 **Choose your encoding** - Supports `Sqids` (default) and `Hashids`, or use your own custom encoder
19
+ * 👓 **Human-readable** - Character grouping & character mappings of easily confused characters for better readability
20
+ * 🔡 **Custom alphabets** - Use your preferred character set, or a provided default
21
+ * 🚗 **Performance** - Uses an optimized `Hashids` encoder (compared to `hashids` gem) for better performance and less memory usage, and have pushed performance improvements to `Sqids` as well
22
+ * 🤬 **Blocklist filtering** - Built-in word blocklist support with configurable modes and optional default lists
27
23
 
28
- ```ruby
29
- class User < ApplicationRecord
30
- include EncodedId::Model
31
-
32
- # An optional slug for the encoded ID string. This is prepended to the encoded ID string, and is solely
33
- # to make the ID human friendly, or useful in URLs. It is not required for finding records by encoded ID.
34
- def name_for_encoded_id_slug
35
- full_name
36
- end
37
-
38
- # An optional prefix on the encoded ID string to help identify the model it belongs to.
39
- # Default is to use model's parameterized name, but can be overridden, or disabled.
40
- # Note it is not required for finding records by encoded ID.
41
- def annotation_for_encoded_id
42
- "usr"
43
- end
44
- end
45
-
46
- # You can find by the encoded ID
47
- user = User.find_by_encoded_id("p5w9-z27j") # => #<User id: 78>
48
- user.encoded_id # => "usr_p5w9-z27j"
49
- user.slugged_encoded_id # => "bob-smith--usr_p5w9-z27j"
50
-
51
- # You can find by a slugged & annotated encoded ID
52
- user == User.find_by_encoded_id("bob-smith--usr_p5w9-z27j") # => true
53
-
54
- # Encoded IDs can encode multiple IDs at the same time
55
- users = User.find_all_by_encoded_id("7aq60zqw") # => [#<User id: 78>, #<User id: 45>]
56
- ```
57
-
58
- ## Why this gem?
59
-
60
- With this gem you can easily obfuscate your IDs in your URLs, and still be able to find records by using
61
- the encoded IDs. The encoded IDs are meant to be somewhat human friendly, to make communication easier
62
- when sharing encoded IDs with other people.
63
-
64
- * Hashids are reversible, no need to persist the generated Id
65
- * we don't override any AR methods. `encoded_id`s are intentionally **not interchangeable** with normal record `id`s
66
- (ie you can't use `.find` to find by encoded ID or record ID, you must be explicit)
67
- * we support slugged IDs (eg `my-amazing-product--p5w9-z27j`)
68
- * we support multiple model IDs encoded in one `EncodedId` (eg `7aq6-0zqw` might decode to `[78, 45]`)
69
- * the gem is configurable
70
- * encoded IDs can be stable across environments, or not (you can set the salt to different values per environment)
71
-
72
- ## Coming in future (?)
73
-
74
- - support for UUIDs for IDs (which will be encoded as an array of integers)
75
-
76
- ## Installation
77
-
78
- Install the gem and add to the application's Gemfile by executing:
79
-
80
- $ bundle add encoded_id-rails
81
-
82
- If bundler is not being used to manage dependencies, install the gem by executing:
83
-
84
- $ gem install encoded_id-rails
85
-
86
- Then run the generator to add the initializer:
87
-
88
- rails g encoded_id:rails:install
89
-
90
- If you plan to use the `EncodedId::Rails::Persists` module to persist encoded IDs, you can generate the necessary migration:
91
-
92
- rails g encoded_id:rails:add_columns User Product # Add to multiple models
93
-
94
- This will create a migration that adds the required columns and indexes to the specified models.
95
-
96
- ## Usage
24
+ ### Rails Integration Features
97
25
 
98
- ### Configuration
26
+ * 🏷️ **ActiveRecord integration** - Use with ActiveRecord models
27
+ * 🔑 **Per-model configuration** - Use custom salt and encoding settings per model
28
+ * 💅 **Slugged IDs** - URL-friendly slugs like `my-product--p5w9-z27j`
29
+ * 🔖 **Annotated IDs** - Model type indicators like `user_p5w9-z27j` (default behavior)
30
+ * 🔍 **Finder methods** - `find_by_encoded_id`, `find_by_encoded_id!`, `find_all_by_encoded_id`, `where_encoded_id`
31
+ * 🛣️ **URL params** - `to_param` automatically uses encoded IDs
32
+ * 🔒 **Safe defaults** - Limits on encoded ID lengths to prevent CPU and memory-intensive encode/decodes when used in URLs
33
+ * 💾 **Persistence** - Optional database persistence for efficient lookups
99
34
 
100
- The install generator will create an initializer file [`config/initializers/encoded_id.rb`](https://github.com/stevegeek/encoded_id-rails/blob/main/lib/generators/encoded_id/rails/templates/encoded_id.rb). It is documented
101
- and should be self-explanatory.
102
35
 
103
- You can configure:
104
-
105
- - a global salt needed to generate the encoded IDs (if you dont use a global salt, you can set a salt per model)
106
- - the size of the character groups in the encoded string (default is 4)
107
- - the separator between the character groups (default is '-')
108
- - the alphabet used to generate the encoded string (default is a variation of the Crockford reduced character set)
109
- - the minimum length of the encoded ID string (default is 8 characters)
110
- - whether models automatically override `to_param` to return the encoded ID (default is false)
111
-
112
- ### ActiveRecord model setup
113
-
114
- Include `EncodedId::Model` in your model and optionally specify a encoded id salt (or not if using a global one):
36
+ ## Quick Example
115
37
 
116
38
  ```ruby
117
- class User < ApplicationRecord
118
- include EncodedId::Model
119
-
120
- # and optionally the model's salt
121
- def encoded_id_salt
122
- "my-user-model-salt"
123
- end
124
-
125
- # ...
126
- end
127
- ```
39
+ # Using Hashids encoder (requires salt)
40
+ coder = ::EncodedId::ReversibleId.hashid(salt: "my-salt")
41
+ coder.encode(123)
42
+ # => "m3pm-8anj"
128
43
 
129
- ### Optional mixins
44
+ # The encoded strings are reversible
45
+ coder.decode("m3pm-8anj")
46
+ # => [123]
130
47
 
131
- You can optionally include one of the following mixins to add default overrides to `#to_param`.
48
+ # Supports encoding multiple IDs at once
49
+ coder.encode([78, 45])
50
+ # => "ny9y-sd7p"
132
51
 
133
- - `EncodedId::PathParam` - Makes `to_param` return the encoded ID
134
- - `EncodedId::SluggedPathParam` - Makes `to_param` return the slugged encoded ID
52
+ # Using Sqids encoder (default, no salt required)
53
+ sqids_coder = ::EncodedId::ReversibleId.sqids
54
+ sqids_coder.encode(123)
55
+ # => (encoded value varies)
135
56
 
136
- This is so that an instance of the model can be used in path helpers and
137
- return the encoded ID string instead of the record ID by default.
138
-
139
- ```ruby
57
+ # Can also be used with ActiveRecord models
140
58
  class User < ApplicationRecord
141
- include EncodedId::Model
142
- include EncodedId::SluggedPathParam
59
+ include EncodedId::Rails::Model
143
60
 
61
+ # Optional: define method to provide slug for encoded ID
144
62
  def name_for_encoded_id_slug
145
63
  full_name
146
64
  end
147
65
  end
148
66
 
149
- user = User.create(full_name: "Bob Smith")
150
- Rails.application.routes.url_helpers.user_path(user) # => "/users/bob-smith--p5w9-z27j"
67
+ # Find by encoded ID
68
+ user = User.find_by_encoded_id("p5w9-z27j") # => #<User id: 78>
69
+ user.encoded_id # => "user_p5w9-z27j"
70
+ user.slugged_encoded_id # => "bob-smith--user_p5w9-z27j"
151
71
  ```
152
72
 
153
- Alternatively, you can configure the gem to automatically override `to_param` for all models that include `EncodedId::Model` by setting the `model_to_param_returns_encoded_id` configuration option to `true`:
73
+ ## Standalone Gem
154
74
 
155
- ```ruby
156
- # In config/initializers/encoded_id.rb
157
- EncodedId::Rails.configure do |config|
158
- # ... other configuration options
159
- config.model_to_param_returns_encoded_id = true
160
- end
161
75
 
162
- # Then in your model
163
- class User < ApplicationRecord
164
- include EncodedId::Model # to_param will automatically return encoded_id
165
- end
76
+ ```bash
77
+ # Add to Gemfile
78
+ bundle add encoded_id
166
79
 
167
- user = User.create(name: "Bob Smith")
168
- Rails.application.routes.url_helpers.user_path(user) # => "/users/user_p5w9-z27j"
80
+ # Or install directly
81
+ gem install encoded_id
169
82
  ```
170
83
 
171
- With this configuration, all models will behave as if they included `EncodedId::PathParam`.
172
-
173
- ### Persisting encoded IDs
84
+ See the [EncodedId API](https://encoded-id.onrender.com/docs/encoded_id/api) documentation for more details.
174
85
 
175
- You can optionally include the `EncodedId::Rails::Persists` mixin to persist the encoded ID in the database. This allows you to query directly by encoded ID in the database and enables more efficient lookups.
176
-
177
- To use this feature, you can either:
178
-
179
- 1. Use the generator to create a migration for your models:
86
+ ## Rails Integration Gem
180
87
 
181
88
  ```bash
182
- rails g encoded_id:rails:add_columns User Product
183
- ```
89
+ # Add to Gemfile
90
+ bundle add encoded_id-rails
184
91
 
185
- 2. Or manually add the following columns to your model's table:
186
-
187
- ```ruby
188
- add_column :users, :normalized_encoded_id, :string
189
- add_column :users, :prefixed_encoded_id, :string
190
- add_index :users, :normalized_encoded_id, unique: true
191
- add_index :users, :prefixed_encoded_id, unique: true
92
+ # Then run the generator
93
+ rails g encoded_id:rails:install
192
94
  ```
193
95
 
194
- Then include the mixin in your model:
96
+ See the [Rails Integration](https://encoded-id.onrender.com/docs/encoded_id_rails) documentation for more details.
195
97
 
196
- ```ruby
197
- class User < ApplicationRecord
198
- include EncodedId::Model
199
- include EncodedId::Rails::Persists
200
- end
201
- ```
98
+ ## Security Note
202
99
 
203
- The mixin will:
100
+ **Encoded IDs are not secure**. They are meant to provide obfuscation, not encryption. Do not use them as a security mechanism.
204
101
 
205
- 1. Store the encoded ID hash (without character grouping) in the `normalized_encoded_id` column
206
- 2. Store the complete encoded ID (with prefix if any) in the `prefixed_encoded_id` column
207
- 3. Add validations to ensure these columns are unique
208
- 4. Make these columns readonly after creation
209
- 5. Automatically update the persisted encoded IDs when the record is created
210
- 6. Ensure encoded IDs are reset when a record is duplicated
211
- 7. Provide safeguards to prevent inconsistencies
102
+ As of version 1.0.0, `Sqids` is the default encoder. `Hashids` is still supported but is officially deprecated by the Hashids project in favor of Sqids.
212
103
 
213
- This enables direct database queries by encoded ID without having to decode them first. It also allows you to create database indexes on these columns for more efficient lookups.
104
+ Read more about the security implications: [Hashids expose salt value](https://www.sjoerdlangkemper.nl/2023/11/25/hashids-expose-salt-value/) (note: this specifically applies to Hashids encoder)
214
105
 
215
- #### Example Usage of Persisted Encoded IDs
106
+ ## Compare to Alternate Gems
216
107
 
217
- Once you've set up the necessary database columns and included the `Persists` module, you can use the persisted encoded IDs:
108
+ - [prefixed_ids](https://github.com/excid3/prefixed_ids)
109
+ - [obfuscate_id](https://github.com/namick/obfuscate_id)
110
+ - [friendly_id](https://github.com/norman/friendly_id)
111
+ - [with_uid](https://github.com/SPBTV/with_uid)
112
+ - [bullet_train-obfuscates_id](https://github.com/bullet-train-co/bullet_train-core/blob/main/bullet_train-obfuscates_id/app/models/concerns/obfuscates_id.rb)
218
113
 
219
- ```ruby
220
- # Creating a record automatically sets the encoded IDs
221
- user = User.create(name: "Bob Smith")
222
- user.normalized_encoded_id # => "p5w9z27j" (encoded ID without character grouping)
223
- user.prefixed_encoded_id # => "user_p5w9-z27j" (complete encoded ID with prefix)
224
-
225
- # You can use these in ActiveRecord queries now of course, eg
226
- User.where(normalized_encoded_id: ["p5w9z27j", "7aq60zqw"])
227
-
228
- # If you need to refresh the encoded ID (e.g., you changed the salt)
229
- user.set_normalized_encoded_id!
230
-
231
- # The module protects against direct changes to these attributes
232
- user.normalized_encoded_id = "something-else"
233
- user.save # This will raise ActiveRecord::ReadonlyAttributeError
234
- ```
114
+ For a detailed comparison, see the [Compared to Other Gems](https://encoded-id.onrender.com/docs/compared-to) documentation page.
235
115
 
236
116
  ## Documentation
237
117
 
238
- ### `.find_by_encoded_id`
239
-
240
- Like `.find` but accepts an encoded ID string instead of an ID. Will return `nil` if no record is found.
241
-
242
- ```ruby
243
- user = User.find_by_encoded_id("p5w9-z27j") # => #<User id: 78>
244
- user.encoded_id # => "p5w9-z27j"
245
- ```
246
-
247
- Note when an encoded ID string contains multiple IDs, this method will return the record for the first ID.
248
-
249
- ### `.find_by_encoded_id!`
250
-
251
- Like `.find!` but accepts an encoded ID string instead of an ID. Raises `ActiveRecord::RecordNotFound` if no record is found.
252
-
253
- ```ruby
254
- user = User.find_by_encoded_id!("p5w9-z27j") # => #<User id: 78>
255
-
256
- # raises ActiveRecord::RecordNotFound
257
- user = User.find_by_encoded_id!("encoded-id-that-is-not-found") # => ActiveRecord::RecordNotFound
258
- ```
259
-
260
- Note when an encoded ID string contains multiple IDs, this method will return the record for the first ID.
261
-
262
- ### `.find_all_by_encoded_id`
263
-
264
- Like `.find_by_encoded_id` but when an encoded ID string contains multiple IDs,
265
- this method will return an array of records.
266
-
267
- ### `.find_all_by_encoded_id!`
268
-
269
- Like `.find_by_encoded_id!` but when an encoded ID string contains multiple IDs,
270
- this method will return an array of records.
271
-
272
- ### `.where_encoded_id`
273
-
274
- A helper for creating relations. Decodes the encoded ID string before passing it to `.where`.
275
-
276
- ```ruby
277
- encoded_id = User.encode_encoded_id([user1.id, user2.id]) # => "7aq6-0zqw"
278
- User.where(active: true)
279
- .where_encoded_id(encoded_id)
280
- .map(&:name) # => ["Bob Smith", "Jane Doe"]
281
- ```
282
-
283
- ### `.encode_encoded_id`
284
-
285
- Encodes an ID or array of IDs into an encoded ID string.
286
-
287
- ```ruby
288
- User.encode_encoded_id(78) # => "p5w9-z27j"
289
- User.encode_encoded_id([78, 45]) # => "7aq6-0zqw"
290
- ```
291
-
292
- ### `.decode_encoded_id`
293
-
294
- Decodes an encoded ID string into an array of IDs.
295
-
296
- ```ruby
297
- User.decode_encoded_id("p5w9-z27j") # => [78]
298
- User.decode_encoded_id("7aq6-0zqw") # => [78, 45]
299
- ```
300
-
301
- ### `.encoded_id_salt`
302
-
303
- Returns the salt used to generate the encoded ID string. If not defined, the global salt is used
304
- with `EncodedId::Rails::Salt` to generate a model specific one.
305
-
306
- ```ruby
307
- User.encoded_id_salt # => "User/the-salt-from-the-initializer"
308
- ```
309
-
310
- Otherwise override this method to return a salt specific to the model.
311
-
312
- ```ruby
313
- class User < ApplicationRecord
314
- include EncodedId::Model
315
-
316
- def encoded_id_salt
317
- "my-user-model-salt"
318
- end
319
- end
320
-
321
- User.encoded_id_salt # => "my-user-model-salt"
322
- ```
323
-
324
- ### `#encoded_id_hash`
325
-
326
- Returns only the encoded 'hashId' part of the encoded ID for the record (without any annotation):
327
-
328
- ```ruby
329
- user = User.create(name: "Bob Smith")
330
- user.encoded_id_hash # => "p5w9-z27j"
331
- ```
332
-
333
-
334
- ### `#encoded_id`
335
-
336
- Returns the encoded ID for the record, with an annotation (if it is enabled):
337
-
338
- ```ruby
339
- user = User.create(name: "Bob Smith")
340
- user.encoded_id # => "user_p5w9-z27j"
341
- ```
342
-
343
- By default, the annotation comes from the underscored model name. However, you can change this by either:
344
-
345
- - overriding `#annotation_for_encoded_id` on the model
346
- - overriding `#annotation_for_encoded_id` on all models via your `ApplicationRecord`
347
- - change the method called to get the annotation via setting the `annotation_method_name` config options in your initializer
348
- - disable the annotation via setting the `annotation_method_name` config options in your initializer to `nil`
349
-
350
-
351
- Examples:
352
-
353
- ```ruby
354
- EncodedId::Rails.configuration.annotation_method_name = :name
355
- user.encoded_id # => "bob_smith_p5w9-z27j"
356
- ```
357
-
358
- ```ruby
359
- EncodedId::Rails.configuration.annotation_method_name = nil
360
- user.encoded_id # => "p5w9-z27j"
361
- ```
362
-
363
- ```ruby
364
- class User < ApplicationRecord
365
- include EncodedId::Model
366
-
367
- def annotation_for_encoded_id
368
- "foo"
369
- end
370
- end
371
-
372
- user = User.create(name: "Bob Smith")
373
- user.encoded_id # => "foo_p5w9-z27j"
374
- ```
375
-
376
- Note that you can also configure the annotation separator via the `annotated_id_separator` config option in your initializer,
377
- but it must be set to a string that only contains character that are not part of the alphabet used to encode the ID.
378
-
379
- ```ruby
380
- EncodedId::Rails.configuration.annotated_id_separator = "^^"
381
- user.encoded_id # => "foo^^p5w9-z27j"
382
- ```
383
-
384
- ### `#slugged_encoded_id`
385
-
386
- Use the `slugged_encoded_id` instance method to get the slugged version of the encoded ID for the record.
387
-
388
- ```ruby
389
- user = User.create(name: "Bob Smith")
390
- user.slugged_encoded_id # => "bob-smith--p5w9-z27j"
391
- ```
392
-
393
- Calls `#name_for_encoded_id_slug` on the record to get the slug part of the encoded ID.
394
- By default, `#name_for_encoded_id_slug` raises, and must be overridden, or configured via the `slug_value_method_name` config option in your initializer:
395
-
396
- ```ruby
397
- class User < ApplicationRecord
398
- include EncodedId::Model
399
-
400
- # Assuming user has a name attribute
401
- def name_for_encoded_id_slug
402
- name
403
- end
404
- end
405
-
406
- user = User.create(name: "Bob Smith")
407
- user.slugged_encoded_id # => "bob-smith--p5w9-z27j"
408
- ```
409
-
410
- You can optionally override this method to define your own slug:
411
-
412
- ```ruby
413
- class User < ApplicationRecord
414
- include EncodedId::Model
415
-
416
- def name_for_encoded_id_slug
417
- superhero_name
418
- end
419
- end
420
-
421
- user = User.create(superhero_name: "Super Dev")
422
- user.slugged_encoded_id # => "super-dev--37nw-8nh7"
423
- ```
424
-
425
- Configure the method called by setting the `slug_value_method_name` config option in your initializer:
426
-
427
- ```ruby
428
- EncodedId::Rails.configuration.slug_value_method_name = :name
429
- user.slugged_encoded_id # => "bob-smith--p5w9-z27j"
430
- ```
431
-
432
- Note that you can also configure the slug separator via the `slugged_id_separator` config option in your initializer,
433
- but it must be set to a string that only contains character that are not part of the alphabet used to encode the ID.
434
-
435
- ```ruby
436
- EncodedId::Rails.configuration.slugged_id_separator = "***"
437
- user.slugged_encoded_id # => "bob-smith***p5w9-z27j"
438
- ```
439
-
440
- ## To use on all models
441
-
442
- Simply add the mixin to your `ApplicationRecord`:
443
-
444
- ```ruby
445
- class ApplicationRecord < ActiveRecord::Base
446
- self.abstract_class = true
447
- include EncodedId::Model
448
-
449
- ...
450
- end
451
- ```
452
-
453
- However, I recommend you only use it on the models that need it.
454
-
455
- ## Example usage for a route and controller
456
-
457
- ```ruby
458
- # Route
459
- resources :users, param: :encoded_id, only: [:show]
460
- ```
461
-
462
- ```ruby
463
- # Model
464
- class User < ApplicationRecord
465
- include EncodedId::Model
466
- include EncodedId::PathParam
467
- end
468
- ```
469
-
470
- ```ruby
471
- # Controller
472
- class UsersController < ApplicationController
473
- def show
474
- @user = User.find_by_encoded_id!(params[:encoded_id])
475
- end
476
- end
477
- ```
478
-
479
- ```erb
480
- <%= link_to "User", user_path %>
481
- ```
482
-
483
- ## Performance Considerations
484
-
485
- The performance of encoding and decoding IDs depends on several factors:
486
-
487
- 1. **ID Length**: The longer the minimum ID length specified in configuration (`id_length`), the slower the encoding and decoding process will be. This is because the underlying Hashids algorithm has to do more work to generate longer IDs. If performance is critical, consider using shorter ID lengths, but be aware of the security tradeoffs.
488
-
489
- 2. **Encoding Multiple IDs**: Encoding multiple IDs in a single string is more computationally expensive than encoding a single ID.
490
-
491
- 3. **Database Queries**: When using `find_by_encoded_id` or `where_encoded_id`, each lookup requires decoding first. Consider using the `Persists` module to store encoded IDs if this is an issue.
492
-
493
- 4. **Character Grouping**: Using character grouping with separators adds a small overhead to encoding and decoding.
494
-
495
- For detailed performance metrics and benchmarks, refer to the [EncodedId gem documentation](https://github.com/stevegeek/encoded_id).
118
+ Visit [encoded-id.onrender.com](https://encoded-id.onrender.com) for comprehensive documentation including:
496
119
 
120
+ - [EncodedId Core Guide](https://encoded-id.onrender.com/docs/encoded_id/) - Installation, configuration, examples, and advanced topics
121
+ - [EncodedId Rails Guide](https://encoded-id.onrender.com/docs/encoded_id_rails/) - Rails integration, configuration, and examples
122
+ - [EncodedId Core API Reference](https://encoded-id.onrender.com/docs/encoded_id/api)
123
+ - [Rails Integration API Reference](https://encoded-id.onrender.com/docs/encoded_id_rails/api)
497
124
 
498
125
  ## Development
499
126
 
500
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
127
+ After checking out the repo, run `bin/setup` to install dependencies. Run `bundle exec rake test` to run the tests.
501
128
 
502
- To run tests with code coverage:
129
+ Run benchmarks with `bin/benchmark <type>` where type is one of: `ips`, `memory`, `comparison`, `profile`, `flamegraph`, or `stress_decode`.
503
130
 
504
- ```bash
505
- bundle exec rake coverage
506
- ```
507
-
508
- This will generate a coverage report in the `coverage` directory that you can open in your browser.
509
-
510
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
511
-
512
- ### Type check
513
-
514
- First install dependencies:
515
-
516
- ```bash
517
- rbs collection install
518
- ```
519
-
520
- Then run:
521
-
522
- ```bash
523
- steep check
524
- ```
131
+ ### Documentation
525
132
 
133
+ Run `bundle exec rake website:build` to build or `bundle exec rake website:serve` to preview locally.
526
134
 
527
135
  ## Contributing
528
136
 
529
- Bug reports and pull requests are welcome on GitHub at https://github.com/stevegeek/encoded_id-rails.
137
+ Bug reports and pull requests are welcome on GitHub at https://github.com/stevegeek/encoded_id.
530
138
 
531
139
  ## License
532
140
 
533
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
141
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).