encoded_id-rails 0.6.2 → 1.0.0.beta1
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.
Potentially problematic release.
This version of encoded_id-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -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 +29 -13
- 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,28 @@
|
|
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
|
+
|
3
26
|
## [0.6.2] - 2023-02-09
|
4
27
|
|
5
28
|
- Fix `encoded_id` memoization clearing when record is duplicated
|
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
58
|
new_record.send(:remove_instance_variable, :@encoded_id) if new_record.instance_variable_defined?(:@encoded_id)
|
43
|
-
new_record.send(:remove_instance_variable, :@slugged_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
|