encoded_id-rails 0.6.1 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of encoded_id-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/Gemfile +2 -2
- data/README.md +105 -13
- data/Steepfile +0 -2
- data/lib/encoded_id/rails/annotated_id.rb +22 -0
- data/lib/encoded_id/rails/annotated_id_parser.rb +19 -0
- data/lib/encoded_id/rails/configuration.rb +7 -1
- data/lib/encoded_id/rails/encoder_methods.rb +2 -5
- data/lib/encoded_id/rails/finder_methods.rb +22 -8
- data/lib/encoded_id/rails/model.rb +30 -14
- data/lib/encoded_id/rails/path_param.rb +1 -1
- data/lib/encoded_id/rails/slugged_id.rb +6 -9
- data/lib/encoded_id/rails/slugged_path_param.rb +1 -1
- data/lib/encoded_id/rails/version.rb +1 -1
- data/lib/encoded_id/rails.rb +2 -0
- data/rbs_collection.yaml +0 -2
- data/sig/encoded_id/rails.rbs +38 -15
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6279bf9520a50983edc402bdc6a94fd4888c7c77f3c50484841535962ce50cc0
|
4
|
+
data.tar.gz: 4fdbddfc863dbe9acd25c4ad51551aef70c0c4972a5d18d29a134a848d73e5e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0784b0541785da4f291f8a303674c72598622016693efb060adc3a8cd75fd68b1299b755e381777ecf45616e3217e05f9fe9eefccf53dce2d6fb3e118bd1313e'
|
7
|
+
data.tar.gz: 01fba9fb0fb764cfac1953997da5637915b55badd90e586f01c60eda9ab4182d4a2fe9be531e420fbe95172442d4e2e12346c8422e06f26c86541a9000648ab2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.0.0.beta1] - 2023-08-07
|
4
|
+
|
5
|
+
### Breaking changes
|
6
|
+
|
7
|
+
- `#encoded_id` now defaults to returning an 'annotated' ID, one in which a prefix is added to the encoded ID to indicate
|
8
|
+
the 'type' of the record the ID represents. This can be disabled. IDs generated by older versions of this gem will
|
9
|
+
decode correctly. But not that IDs generated by this version onwards will not decode correctly by older versions of this
|
10
|
+
gem so make sure to disable annotation if you need to support older versions of this gem.
|
11
|
+
- `#name_for_encoded_id_slug` no longer provides a default implementation, it is up to the user to define this method,
|
12
|
+
or configure the gem to use a different method name.
|
13
|
+
- `#slugged_encoded_id` no longer takes a `with:` parameter. To specify the name of the method to call to generate the
|
14
|
+
slug, use the `slug_value_method_name` configuration option.
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- `#encoded_id_hash` has been added to return only the encoded ID without an annotation prefix. If annotation is disabled,
|
19
|
+
this method is basically an alias to `#encoded_id`.
|
20
|
+
- `.find_all_by_encoded_id` has been added to return all records matching the given encoded ID. This will return all
|
21
|
+
matching records whose IDs are encoded in the encoded_id. Missing records are ignored.
|
22
|
+
- `.find_all_by_encoded_id!` like `.find_all_by_encoded_id` but raises an `ActiveRecord::RecordNotFound` exception if
|
23
|
+
*any* of the records are not found.
|
24
|
+
|
25
|
+
|
26
|
+
## [0.6.2] - 2023-02-09
|
27
|
+
|
28
|
+
- Fix `encoded_id` memoization clearing when record is duplicated
|
29
|
+
|
3
30
|
## [0.6.1] - 2023-02-09
|
4
31
|
|
5
32
|
- Fix `#encoded_id` to return nil if `#id` is nil
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -8,20 +8,37 @@ EncodedID lets you turn numeric or hex IDs into reversible and human friendly ob
|
|
8
8
|
class User < ApplicationRecord
|
9
9
|
include EncodedId::Model
|
10
10
|
|
11
|
+
# An optional slug for the encoded ID string. This is prepended to the encoded ID string, and is solely
|
12
|
+
# to make the ID human friendly, or useful in URLs. It is not required for finding records by encoded ID.
|
11
13
|
def name_for_encoded_id_slug
|
12
14
|
full_name
|
13
15
|
end
|
16
|
+
|
17
|
+
# An optional prefix on the encoded ID string to help identify the model it belongs to.
|
18
|
+
# Default is to use model's parameterized name, but can be overridden, or disabled.
|
19
|
+
# Note it is not required for finding records by encoded ID.
|
20
|
+
def annotation_for_encoded_id
|
21
|
+
"usr"
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
25
|
+
# You can find by the encoded ID
|
16
26
|
user = User.find_by_encoded_id("p5w9-z27j") # => #<User id: 78>
|
17
|
-
user.encoded_id # => "
|
18
|
-
user.slugged_encoded_id # => "bob-smith--
|
27
|
+
user.encoded_id # => "usr_p5w9-z27j"
|
28
|
+
user.slugged_encoded_id # => "bob-smith--usr_p5w9-z27j"
|
29
|
+
|
30
|
+
# You can find by a slugged & annotated encoded ID
|
31
|
+
user == User.find_by_encoded_id("bob-smith--usr_p5w9-z27j") # => true
|
32
|
+
|
33
|
+
# Encoded IDs can encode multiple IDs at the same time
|
34
|
+
users = User.find_all_by_encoded_id("7aq60zqw") # => [#<User id: 78>, #<User id: 45>]
|
19
35
|
```
|
20
36
|
|
21
37
|
# Features
|
22
38
|
|
23
39
|
- encoded IDs are reversible (see [`encoded_id`](https://github.com/stevegeek/encoded_id))
|
24
40
|
- supports slugged IDs (eg `my-cool-product-name--p5w9-z27j`) that are URL friendly (assuming your alphabet is too)
|
41
|
+
- 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`)
|
25
42
|
- encoded string can be split into groups of letters to improve human-readability (eg `abcd-efgh`)
|
26
43
|
- supports multiple IDs encoded in one encoded string (eg imagine the encoded ID `7aq60zqw` might decode to two IDs `[78, 45]`)
|
27
44
|
- supports custom alphabets for the encoded string (at least 16 characters needed)
|
@@ -135,6 +152,8 @@ user = User.find_by_encoded_id("p5w9-z27j") # => #<User id: 78>
|
|
135
152
|
user.encoded_id # => "p5w9-z27j"
|
136
153
|
```
|
137
154
|
|
155
|
+
Note when an encoded ID string contains multiple IDs, this method will return the record for the first ID.
|
156
|
+
|
138
157
|
### `.find_by_encoded_id!`
|
139
158
|
|
140
159
|
Like `.find!` but accepts an encoded ID string instead of an ID. Raises `ActiveRecord::RecordNotFound` if no record is found.
|
@@ -146,6 +165,18 @@ user = User.find_by_encoded_id!("p5w9-z27j") # => #<User id: 78>
|
|
146
165
|
user = User.find_by_encoded_id!("encoded-id-that-is-not-found") # => ActiveRecord::RecordNotFound
|
147
166
|
```
|
148
167
|
|
168
|
+
Note when an encoded ID string contains multiple IDs, this method will return the record for the first ID.
|
169
|
+
|
170
|
+
### `.find_all_by_encoded_id`
|
171
|
+
|
172
|
+
Like `.find_by_encoded_id` but when an encoded ID string contains multiple IDs,
|
173
|
+
this method will return an array of records.
|
174
|
+
|
175
|
+
### `.find_all_by_encoded_id!`
|
176
|
+
|
177
|
+
Like `.find_by_encoded_id!` but when an encoded ID string contains multiple IDs,
|
178
|
+
this method will return an array of records.
|
179
|
+
|
149
180
|
### `.where_encoded_id`
|
150
181
|
|
151
182
|
A helper for creating relations. Decodes the encoded ID string before passing it to `.where`.
|
@@ -198,44 +229,90 @@ end
|
|
198
229
|
User.encoded_id_salt # => "my-user-model-salt"
|
199
230
|
```
|
200
231
|
|
232
|
+
### `#encoded_id_hash`
|
233
|
+
|
234
|
+
Returns only the encoded 'hashId' part of the encoded ID for the record:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
user = User.create(name: "Bob Smith")
|
238
|
+
user.encoded_id # => "p5w9-z27j"
|
239
|
+
```
|
240
|
+
|
241
|
+
|
201
242
|
### `#encoded_id`
|
202
243
|
|
203
|
-
|
244
|
+
Returns the encoded ID for the record, with an annotation (if it is enabled):
|
204
245
|
|
205
246
|
```ruby
|
206
247
|
user = User.create(name: "Bob Smith")
|
248
|
+
user.encoded_id # => "user_p5w9-z27j"
|
249
|
+
```
|
250
|
+
|
251
|
+
By default, the annotation comes from the underscored model name. However, you can change this by either:
|
252
|
+
|
253
|
+
- overriding `#annotation_for_encoded_id` on the model
|
254
|
+
- overriding `#annotation_for_encoded_id` on all models via your `ApplicationRecord`
|
255
|
+
- change the method called to get the annotation via setting the `annotation_method_name` config options in your initializer
|
256
|
+
- disable the annotation via setting the `annotation_method_name` config options in your initializer to `nil`
|
257
|
+
|
258
|
+
|
259
|
+
Examples:
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
EncodedId::Rails.configuration.annotation_method_name = :name
|
263
|
+
user.encoded_id # => "bob_smith_p5w9-z27j"
|
264
|
+
```
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
EncodedId::Rails.configuration.annotation_method_name = nil
|
207
268
|
user.encoded_id # => "p5w9-z27j"
|
208
269
|
```
|
209
270
|
|
271
|
+
```ruby
|
272
|
+
class User < ApplicationRecord
|
273
|
+
include EncodedId::Model
|
274
|
+
|
275
|
+
def annotation_for_encoded_id
|
276
|
+
"foo"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
user = User.create(name: "Bob Smith")
|
281
|
+
user.encoded_id # => "foo_p5w9-z27j"
|
282
|
+
```
|
283
|
+
|
284
|
+
Note that you can also configure the annotation separator via the `annotated_id_separator` config option in your initializer,
|
285
|
+
but it must be set to a string that only contains character that are not part of the alphabet used to encode the ID.
|
286
|
+
|
287
|
+
```ruby
|
288
|
+
EncodedId::Rails.configuration.annotated_id_separator = "^^"
|
289
|
+
user.encoded_id # => "foo^^p5w9-z27j"
|
290
|
+
```
|
210
291
|
|
211
292
|
### `#slugged_encoded_id`
|
212
293
|
|
213
294
|
Use the `slugged_encoded_id` instance method to get the slugged version of the encoded ID for the record.
|
214
|
-
Calls `#name_for_encoded_id_slug` on the record to get the slug part of the encoded ID:
|
215
295
|
|
216
296
|
```ruby
|
217
297
|
user = User.create(name: "Bob Smith")
|
218
298
|
user.slugged_encoded_id # => "bob-smith--p5w9-z27j"
|
219
299
|
```
|
220
300
|
|
221
|
-
|
222
|
-
|
223
|
-
Use `#name_for_encoded_id_slug` to specify what will be used to create the slug part of the encoded ID.
|
224
|
-
By default it calls `#name` on the instance, or if the instance does not respond to
|
225
|
-
`name` (or the value returned is blank) then uses the Model name.
|
301
|
+
Calls `#name_for_encoded_id_slug` on the record to get the slug part of the encoded ID.
|
302
|
+
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:
|
226
303
|
|
227
304
|
```ruby
|
228
305
|
class User < ApplicationRecord
|
229
306
|
include EncodedId::Model
|
230
307
|
|
231
|
-
#
|
232
|
-
|
308
|
+
# Assuming user has a name attribute
|
309
|
+
def name_for_encoded_id_slug
|
310
|
+
name
|
311
|
+
end
|
233
312
|
end
|
234
313
|
|
235
314
|
user = User.create(name: "Bob Smith")
|
236
315
|
user.slugged_encoded_id # => "bob-smith--p5w9-z27j"
|
237
|
-
user2 = User.create(name: "")
|
238
|
-
user2.slugged_encoded_id # => "user--i74r-bn28"
|
239
316
|
```
|
240
317
|
|
241
318
|
You can optionally override this method to define your own slug:
|
@@ -253,6 +330,21 @@ user = User.create(superhero_name: "Super Dev")
|
|
253
330
|
user.slugged_encoded_id # => "super-dev--37nw-8nh7"
|
254
331
|
```
|
255
332
|
|
333
|
+
Configure the method called by setting the `slug_value_method_name` config option in your initializer:
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
EncodedId::Rails.configuration.slug_value_method_name = :name
|
337
|
+
user.slugged_encoded_id # => "bob-smith--p5w9-z27j"
|
338
|
+
```
|
339
|
+
|
340
|
+
Note that you can also configure the slug separator via the `slugged_id_separator` config option in your initializer,
|
341
|
+
but it must be set to a string that only contains character that are not part of the alphabet used to encode the ID.
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
EncodedId::Rails.configuration.annotated_id_separator = "***"
|
345
|
+
user.encoded_id # => "bob-smith***p5w9-z27j"
|
346
|
+
```
|
347
|
+
|
256
348
|
## To use on all models
|
257
349
|
|
258
350
|
Simply add the mixin to your `ApplicationRecord`:
|
data/Steepfile
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
4
|
+
|
5
|
+
module EncodedId
|
6
|
+
module Rails
|
7
|
+
class AnnotatedId
|
8
|
+
def initialize(annotation:, id_part:, separator: "_")
|
9
|
+
@annotation = annotation
|
10
|
+
@id_part = id_part
|
11
|
+
@separator = separator
|
12
|
+
end
|
13
|
+
|
14
|
+
def annotated_id
|
15
|
+
unless @id_part.present? && @annotation.present?
|
16
|
+
raise ::StandardError, "The model does not provide a valid ID and/or annotation"
|
17
|
+
end
|
18
|
+
"#{@annotation.to_s.parameterize}#{CGI.escape(@separator)}#{@id_part}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EncodedId
|
4
|
+
module Rails
|
5
|
+
class AnnotatedIdParser
|
6
|
+
def initialize(annotated_id, separator: "_")
|
7
|
+
if separator && annotated_id.include?(separator)
|
8
|
+
parts = annotated_id.split(separator)
|
9
|
+
@id = parts.last
|
10
|
+
@annotation = parts[0..-2]&.join(separator)
|
11
|
+
else
|
12
|
+
@id = annotated_id
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :annotation, :id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -9,14 +9,20 @@ module EncodedId
|
|
9
9
|
:group_separator,
|
10
10
|
:alphabet,
|
11
11
|
:id_length,
|
12
|
-
:
|
12
|
+
:slug_value_method_name,
|
13
|
+
:slugged_id_separator,
|
14
|
+
:annotation_method_name, # Set to nil to disable annotated IDs
|
15
|
+
:annotated_id_separator
|
13
16
|
|
14
17
|
def initialize
|
15
18
|
@character_group_size = 4
|
16
19
|
@group_separator = "-"
|
17
20
|
@alphabet = ::EncodedId::Alphabet.modified_crockford
|
18
21
|
@id_length = 8
|
22
|
+
@slug_value_method_name = :name_for_encoded_id_slug
|
19
23
|
@slugged_id_separator = "--"
|
24
|
+
@annotation_method_name = :annotation_for_encoded_id
|
25
|
+
@annotated_id_separator = "_"
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -10,7 +10,8 @@ module EncodedId
|
|
10
10
|
|
11
11
|
def decode_encoded_id(slugged_encoded_id, options = {})
|
12
12
|
return if slugged_encoded_id.blank?
|
13
|
-
|
13
|
+
annotated_encoded_id = SluggedIdParser.new(slugged_encoded_id, separator: EncodedId::Rails.configuration.slugged_id_separator).id
|
14
|
+
encoded_id = AnnotatedIdParser.new(annotated_encoded_id, separator: EncodedId::Rails.configuration.annotated_id_separator).id
|
14
15
|
return if !encoded_id || encoded_id.blank?
|
15
16
|
encoded_id_coder(options).decode(encoded_id)
|
16
17
|
end
|
@@ -21,10 +22,6 @@ module EncodedId
|
|
21
22
|
EncodedId::Rails::Salt.new(self, EncodedId::Rails.configuration.salt).generate!
|
22
23
|
end
|
23
24
|
|
24
|
-
def encoded_id_parser(slugged_encoded_id)
|
25
|
-
SluggedIdParser.new(slugged_encoded_id, separator: EncodedId::Rails.configuration.slugged_id_separator)
|
26
|
-
end
|
27
|
-
|
28
25
|
def encoded_id_coder(options = {})
|
29
26
|
config = EncodedId::Rails.configuration
|
30
27
|
EncodedId::Rails::Coder.new(
|
@@ -4,24 +4,38 @@ module EncodedId
|
|
4
4
|
module Rails
|
5
5
|
module FinderMethods
|
6
6
|
# Find by encoded ID and optionally ensure record ID is the same as constraint (can be slugged)
|
7
|
-
def find_by_encoded_id(
|
8
|
-
decoded_id = decode_encoded_id(
|
9
|
-
return if decoded_id.blank?
|
10
|
-
record = find_by(id: decoded_id)
|
7
|
+
def find_by_encoded_id(encoded_id, with_id: nil)
|
8
|
+
decoded_id = decode_encoded_id(encoded_id)
|
9
|
+
return if decoded_id.nil? || decoded_id.blank?
|
10
|
+
record = find_by(id: decoded_id.first)
|
11
11
|
return unless record
|
12
12
|
return if with_id && with_id != record.send(:id)
|
13
13
|
record
|
14
14
|
end
|
15
15
|
|
16
|
-
def find_by_encoded_id!(
|
17
|
-
decoded_id = decode_encoded_id(
|
18
|
-
raise ActiveRecord::RecordNotFound if decoded_id.blank?
|
19
|
-
record = find_by(id: decoded_id)
|
16
|
+
def find_by_encoded_id!(encoded_id, with_id: nil)
|
17
|
+
decoded_id = decode_encoded_id(encoded_id)
|
18
|
+
raise ActiveRecord::RecordNotFound if decoded_id.nil? || decoded_id.blank?
|
19
|
+
record = find_by(id: decoded_id.first)
|
20
20
|
if !record || (with_id && with_id != record.send(:id))
|
21
21
|
raise ActiveRecord::RecordNotFound
|
22
22
|
end
|
23
23
|
record
|
24
24
|
end
|
25
|
+
|
26
|
+
def find_all_by_encoded_id(encoded_id)
|
27
|
+
decoded_ids = decode_encoded_id(encoded_id)
|
28
|
+
return if decoded_ids.blank?
|
29
|
+
where(id: decoded_ids).to_a
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_all_by_encoded_id!(encoded_id)
|
33
|
+
decoded_ids = decode_encoded_id(encoded_id)
|
34
|
+
raise ActiveRecord::RecordNotFound if decoded_ids.nil? || decoded_ids.blank?
|
35
|
+
records = where(id: decoded_ids).to_a
|
36
|
+
raise ActiveRecord::RecordNotFound if records.blank? || records.size != decoded_ids.size
|
37
|
+
records
|
38
|
+
end
|
25
39
|
end
|
26
40
|
end
|
27
41
|
end
|
@@ -12,35 +12,51 @@ module EncodedId
|
|
12
12
|
base.extend(QueryMethods)
|
13
13
|
end
|
14
14
|
|
15
|
+
def encoded_id_hash
|
16
|
+
return unless id
|
17
|
+
return @encoded_id_hash if defined?(@encoded_id_hash) && !id_changed?
|
18
|
+
self.class.encode_encoded_id(id)
|
19
|
+
end
|
20
|
+
|
15
21
|
def encoded_id
|
16
22
|
return unless id
|
17
23
|
return @encoded_id if defined?(@encoded_id) && !id_changed?
|
18
|
-
|
24
|
+
encoded = encoded_id_hash
|
25
|
+
annotated_by = EncodedId::Rails.configuration.annotation_method_name
|
26
|
+
return @encoded_id = encoded unless annotated_by && encoded
|
27
|
+
separator = EncodedId::Rails.configuration.annotated_id_separator
|
28
|
+
@encoded_id = EncodedId::Rails::AnnotatedId.new(id_part: encoded, annotation: send(annotated_by.to_s), separator: separator).annotated_id
|
19
29
|
end
|
20
30
|
|
21
|
-
def slugged_encoded_id
|
31
|
+
def slugged_encoded_id
|
22
32
|
return unless id
|
23
33
|
return @slugged_encoded_id if defined?(@slugged_encoded_id) && !id_changed?
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
with = EncodedId::Rails.configuration.slug_value_method_name
|
35
|
+
separator = EncodedId::Rails.configuration.slugged_id_separator
|
36
|
+
encoded = encoded_id
|
37
|
+
return unless encoded
|
38
|
+
@slugged_encoded_id = EncodedId::Rails::SluggedId.new(id_part: encoded, slug_part: send(with.to_s), separator: separator).slugged_id
|
39
|
+
end
|
40
|
+
|
41
|
+
# By default the annotation is the model name (it will be parameterized)
|
42
|
+
def annotation_for_encoded_id
|
43
|
+
name = self.class.name
|
44
|
+
raise StandardError, "The default annotation requires the model class to have a name" if name.nil?
|
45
|
+
name.underscore
|
30
46
|
end
|
31
47
|
|
32
|
-
# By default
|
48
|
+
# By default trying to generate a slug without defining how will raise.
|
49
|
+
# You either override this method per model, pass an alternate method name to
|
50
|
+
# #slugged_encoded_id or setup an alias to another model method in your ApplicationRecord class
|
33
51
|
def name_for_encoded_id_slug
|
34
|
-
|
35
|
-
raise StandardError, "Class must have a `name`, cannot create a slug" if !class_name || class_name.blank?
|
36
|
-
class_name.underscore
|
52
|
+
raise StandardError, "You must define a method to generate the slug for the encoded ID of #{self.class.name}"
|
37
53
|
end
|
38
54
|
|
39
55
|
# When duplicating an ActiveRecord object, we want to reset the memoized encoded_id
|
40
56
|
def dup
|
41
57
|
super.tap do |new_record|
|
42
|
-
new_record.
|
43
|
-
new_record.
|
58
|
+
new_record.send(:remove_instance_variable, :@encoded_id) if new_record.instance_variable_defined?(:@encoded_id)
|
59
|
+
new_record.send(:remove_instance_variable, :@slugged_encoded_id) if new_record.instance_variable_defined?(:@slugged_encoded_id)
|
44
60
|
end
|
45
61
|
end
|
46
62
|
end
|
@@ -5,20 +5,17 @@ require "cgi"
|
|
5
5
|
module EncodedId
|
6
6
|
module Rails
|
7
7
|
class SluggedId
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@id_method = id_method
|
8
|
+
def initialize(slug_part:, id_part:, separator: "--")
|
9
|
+
@slug_part = slug_part
|
10
|
+
@id_part = id_part
|
12
11
|
@separator = separator
|
13
12
|
end
|
14
13
|
|
15
14
|
def slugged_id
|
16
|
-
|
17
|
-
|
18
|
-
unless id_part.present? && slug_part.present?
|
19
|
-
raise ::StandardError, "The model does not return a valid ID (:#{@id_method}) and/or slug (:#{@slug_method})"
|
15
|
+
unless @id_part.present? && @slug_part.present?
|
16
|
+
raise ::StandardError, "The model does not return a valid ID and/or slug"
|
20
17
|
end
|
21
|
-
"#{slug_part.to_s.parameterize}#{CGI.escape(@separator)}#{id_part}"
|
18
|
+
"#{@slug_part.to_s.parameterize}#{CGI.escape(@separator)}#{@id_part}"
|
22
19
|
end
|
23
20
|
end
|
24
21
|
end
|
data/lib/encoded_id/rails.rb
CHANGED
@@ -5,6 +5,8 @@ require_relative "rails/configuration"
|
|
5
5
|
require_relative "rails/coder"
|
6
6
|
require_relative "rails/slugged_id"
|
7
7
|
require_relative "rails/slugged_id_parser"
|
8
|
+
require_relative "rails/annotated_id"
|
9
|
+
require_relative "rails/annotated_id_parser"
|
8
10
|
require_relative "rails/salt"
|
9
11
|
require_relative "rails/encoder_methods"
|
10
12
|
require_relative "rails/query_methods"
|
data/rbs_collection.yaml
CHANGED
data/sig/encoded_id/rails.rbs
CHANGED
@@ -8,7 +8,10 @@ module EncodedId
|
|
8
8
|
attr_accessor character_group_size: ::Integer
|
9
9
|
attr_accessor alphabet: ::EncodedId::Alphabet
|
10
10
|
attr_accessor id_length: ::Integer
|
11
|
+
attr_accessor slug_value_method_name: ::Symbol
|
11
12
|
attr_accessor slugged_id_separator: ::String
|
13
|
+
attr_accessor annotation_method_name: ::Symbol
|
14
|
+
attr_accessor annotated_id_separator: ::String
|
12
15
|
|
13
16
|
def initialize: () -> void
|
14
17
|
end
|
@@ -43,28 +46,41 @@ module EncodedId
|
|
43
46
|
end
|
44
47
|
|
45
48
|
class SluggedId
|
46
|
-
def initialize: (
|
47
|
-
|
48
|
-
@
|
49
|
-
@slug_method: ::Symbol
|
50
|
-
@id_method: ::Symbol
|
49
|
+
def initialize: (slug_part: ::String, id_part: ::String, ?separator: ::String)-> void
|
50
|
+
@slug_part: ::String
|
51
|
+
@id_part: ::String
|
51
52
|
@separator: ::String
|
52
53
|
|
53
54
|
def slugged_id: -> ::String
|
54
55
|
end
|
55
56
|
|
57
|
+
class AnnotatedId
|
58
|
+
def initialize: (annotation: ::String, id_part: ::String, ?separator: ::String)-> void
|
59
|
+
@annotation: ::String
|
60
|
+
@id_part: ::String
|
61
|
+
@separator: ::String
|
62
|
+
|
63
|
+
def annotated_id: -> ::String
|
64
|
+
end
|
65
|
+
|
56
66
|
class SluggedIdParser
|
57
67
|
def initialize: (::String slugged_id, ?separator: ::String) -> void
|
58
68
|
|
59
69
|
attr_reader slug: ::String?
|
60
|
-
attr_reader id: ::String
|
70
|
+
attr_reader id: ::String
|
71
|
+
end
|
72
|
+
|
73
|
+
class AnnotatedIdParser
|
74
|
+
def initialize: (::String annotated_id, ?separator: ::String) -> void
|
75
|
+
|
76
|
+
attr_reader annotation: ::String?
|
77
|
+
attr_reader id: ::String
|
61
78
|
end
|
62
79
|
|
63
80
|
module EncoderMethods
|
64
|
-
def encode_encoded_id: (
|
81
|
+
def encode_encoded_id: (::Array[::Integer] | ::Integer id, ?::Hash[::Symbol, untyped] options) -> ::String
|
65
82
|
def decode_encoded_id: (::String slugged_encoded_id, ?::Hash[::Symbol, untyped] options) -> ::Array[::Integer]?
|
66
83
|
def encoded_id_salt: () -> ::String
|
67
|
-
def encoded_id_parser: (::String slugged_encoded_id) -> ::EncodedId::Rails::SluggedIdParser
|
68
84
|
def encoded_id_coder: (?::Hash[::Symbol, untyped] options) -> ::EncodedId::Rails::Coder
|
69
85
|
end
|
70
86
|
|
@@ -72,9 +88,11 @@ module EncodedId
|
|
72
88
|
def find_by: (*untyped) -> (nil | untyped)
|
73
89
|
end
|
74
90
|
|
75
|
-
module FinderMethods : EncoderMethods, _ActiveRecordFinderMethod
|
76
|
-
def find_by_encoded_id: (::String
|
77
|
-
def find_by_encoded_id!: (::String
|
91
|
+
module FinderMethods : EncoderMethods, _ActiveRecordFinderMethod, _ActiveRecordQueryMethod
|
92
|
+
def find_by_encoded_id: (::String encoded_id, ?with_id: ::Symbol?) -> untyped?
|
93
|
+
def find_by_encoded_id!: (::String encoded_id, ?with_id: ::Symbol?) -> untyped
|
94
|
+
def find_all_by_encoded_id: (::String encoded_id) -> untyped?
|
95
|
+
def find_all_by_encoded_id!: (::String encoded_id) -> untyped
|
78
96
|
end
|
79
97
|
|
80
98
|
interface _ActiveRecordQueryMethod
|
@@ -86,9 +104,12 @@ module EncodedId
|
|
86
104
|
end
|
87
105
|
|
88
106
|
module Model : ActiveRecord::Base
|
107
|
+
# From ActiveRecord
|
89
108
|
extend ActiveRecord::FinderMethods
|
90
109
|
extend ActiveRecord::QueryMethods
|
110
|
+
def id_changed?: -> bool
|
91
111
|
|
112
|
+
# From EncodedId::Rails::Model
|
92
113
|
extend EncoderMethods
|
93
114
|
extend FinderMethods
|
94
115
|
extend QueryMethods
|
@@ -96,13 +117,15 @@ module EncodedId
|
|
96
117
|
@encoded_id: ::String
|
97
118
|
@slugged_encoded_id: ::String
|
98
119
|
|
99
|
-
def
|
100
|
-
def
|
101
|
-
def
|
120
|
+
def encoded_id_hash: -> ::String?
|
121
|
+
def encoded_id: -> ::String?
|
122
|
+
def slugged_encoded_id: -> ::String?
|
123
|
+
def name_for_encoded_id_slug: -> ::String
|
124
|
+
def annotation_for_encoded_id: -> ::String
|
102
125
|
end
|
103
126
|
|
104
127
|
interface _ActiveRecordToParam
|
105
|
-
def to_param:
|
128
|
+
def to_param: -> ::String
|
106
129
|
end
|
107
130
|
|
108
131
|
module PathParam : Model, _ActiveRecordToParam
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: encoded_id-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Ierodiaconou
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -56,14 +56,14 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - "~>"
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
59
|
+
version: 1.0.0.rc1
|
60
60
|
type: :runtime
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version:
|
66
|
+
version: 1.0.0.rc1
|
67
67
|
description: ActiveRecord concern to use EncodedID to turn IDs into reversible and
|
68
68
|
human friendly obfuscated strings.
|
69
69
|
email:
|
@@ -82,6 +82,8 @@ files:
|
|
82
82
|
- gemfiles/rails_6.0.gemfile
|
83
83
|
- gemfiles/rails_7.0.gemfile
|
84
84
|
- lib/encoded_id/rails.rb
|
85
|
+
- lib/encoded_id/rails/annotated_id.rb
|
86
|
+
- lib/encoded_id/rails/annotated_id_parser.rb
|
85
87
|
- lib/encoded_id/rails/coder.rb
|
86
88
|
- lib/encoded_id/rails/configuration.rb
|
87
89
|
- lib/encoded_id/rails/encoder_methods.rb
|
@@ -117,11 +119,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
119
|
version: 2.6.0
|
118
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
121
|
requirements:
|
120
|
-
- - "
|
122
|
+
- - ">"
|
121
123
|
- !ruby/object:Gem::Version
|
122
|
-
version:
|
124
|
+
version: 1.3.1
|
123
125
|
requirements: []
|
124
|
-
rubygems_version: 3.
|
126
|
+
rubygems_version: 3.4.10
|
125
127
|
signing_key:
|
126
128
|
specification_version: 4
|
127
129
|
summary: Use `encoded_id` with ActiveRecord models
|