cool_id 0.1.2 → 0.1.5
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.
- checksums.yaml +4 -4
- data/README.md +74 -16
- data/lib/cool_id/version.rb +1 -1
- data/lib/cool_id.rb +30 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5284982eed15e82c55f1e8a1c853c83feb97d76d7e04fb247b74e6edcbfdcf0e
|
4
|
+
data.tar.gz: 21f44586d37a4a27474dcc984179cc6b8e927ae43da371e5d80874c82a314d43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f8a012d217a3435e87f9df231fce5e850e92cc7ded853fff79cca4f721058f0175912aab2a25c8671defb208453e137884c59a9ec8041a8d1d2aad2f032cb74
|
7
|
+
data.tar.gz: ad7af3d92a6f4b5a067fe535020d9cdd44d53ddd6584ba89555a74bcc83a4cc6a959f7e4cfb857c1961d85dbfe55bd5d0395afe1aed65680d2ae3dab34ab5688
|
data/README.md
CHANGED
@@ -1,31 +1,89 @@
|
|
1
|
-
#
|
1
|
+
# cool_id
|
2
2
|
|
3
|
-
|
3
|
+
a gem for rails that generates string ids for active record models with a per-model prefix followed by a nanoid.
|
4
4
|
|
5
|
-
|
5
|
+
```ruby
|
6
|
+
class User < ActiveRecord::Base
|
7
|
+
include CoolId::Model
|
8
|
+
cool_id prefix: "usr"
|
9
|
+
end
|
6
10
|
|
7
|
-
|
11
|
+
User.create!(name: "...").id
|
12
|
+
# => "usr_vktd1b5v84lr"
|
8
13
|
|
9
|
-
|
14
|
+
class Customer < ActiveRecord::Base
|
15
|
+
include CoolId::Model
|
16
|
+
cool_id prefix: "cus", alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", length: 8
|
17
|
+
end
|
10
18
|
|
11
|
-
|
19
|
+
Customer.create!(name: "...").id
|
20
|
+
# => "cus_UHNYBINU"
|
21
|
+
```
|
12
22
|
|
13
|
-
|
23
|
+
it can also lookup records by ids, similar to global id:
|
14
24
|
|
15
|
-
|
25
|
+
```ruby
|
26
|
+
user = User.create!(name: "John Doe")
|
27
|
+
# => #<User id: "usr_vktd1b5v84lr", name: "John Doe">
|
16
28
|
|
17
|
-
|
29
|
+
CoolId.locate("usr_vktd1b5v84lr")
|
30
|
+
# => #<User id: "usr_vktd1b5v84lr", name: "John Doe">
|
18
31
|
|
19
|
-
|
32
|
+
# You can also parse the id without fetching the record
|
33
|
+
parsed = CoolId.parse("usr_vktd1b5v84lr")
|
34
|
+
# => #<struct CoolId::Id key="vktd1b5v84lr", prefix="usr", id="usr_vktd1b5v84lr", model_class=User>
|
20
35
|
|
21
|
-
|
36
|
+
parsed.model_class
|
37
|
+
# => User
|
38
|
+
```
|
22
39
|
|
23
|
-
##
|
40
|
+
## installation
|
24
41
|
|
25
|
-
|
42
|
+
```bash
|
43
|
+
bundle add cool_id
|
44
|
+
```
|
26
45
|
|
27
|
-
|
46
|
+
```ruby
|
47
|
+
gem "cool_id"
|
48
|
+
```
|
28
49
|
|
29
|
-
|
50
|
+
### per-model
|
30
51
|
|
31
|
-
|
52
|
+
use string ids when creating a table
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
create_table :users, id: :string do |t|
|
56
|
+
t.string :name
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
include the `CoolId::Model` concern in the active record model and set up a prefix
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
class User < ActiveRecord::Base
|
64
|
+
include CoolId::Model
|
65
|
+
cool_id prefix: "usr"
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
### all models
|
70
|
+
|
71
|
+
use string ids on all new generated migrations
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# config/initializers/generators.rb
|
75
|
+
Rails.application.config.generators do |g|
|
76
|
+
g.orm :active_record, primary_key_type: :string
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
setup `ApplicationRecord` to include cool id and ensure it's setup in classes that inherit from it
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
# app/models/application_record.rb
|
84
|
+
class ApplicationRecord < ActiveRecord::Base
|
85
|
+
include CoolId::Model
|
86
|
+
primary_abstract_class
|
87
|
+
enforce_cool_id_for_descendants
|
88
|
+
end
|
89
|
+
```
|
data/lib/cool_id/version.rb
CHANGED
data/lib/cool_id.rb
CHANGED
@@ -7,6 +7,7 @@ require "active_support/concern"
|
|
7
7
|
module CoolId
|
8
8
|
class Error < StandardError; end
|
9
9
|
|
10
|
+
# defaults based on https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
|
10
11
|
DEFAULT_SEPARATOR = "_"
|
11
12
|
DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
|
12
13
|
DEFAULT_LENGTH = 12
|
@@ -27,7 +28,7 @@ module CoolId
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def registry
|
30
|
-
@
|
31
|
+
@prefix_map ||= Registry.new
|
31
32
|
end
|
32
33
|
|
33
34
|
def generate_id(config)
|
@@ -39,18 +40,17 @@ module CoolId
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
# defaults based on https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
|
43
43
|
self.separator = DEFAULT_SEPARATOR
|
44
44
|
self.alphabet = DEFAULT_ALPHABET
|
45
45
|
self.length = DEFAULT_LENGTH
|
46
46
|
|
47
47
|
class Registry
|
48
48
|
def initialize
|
49
|
-
@
|
49
|
+
@prefix_map = {}
|
50
50
|
end
|
51
51
|
|
52
52
|
def register(prefix, model_class)
|
53
|
-
@
|
53
|
+
@prefix_map[prefix] = model_class
|
54
54
|
end
|
55
55
|
|
56
56
|
def locate(id)
|
@@ -60,7 +60,7 @@ module CoolId
|
|
60
60
|
|
61
61
|
def parse(id)
|
62
62
|
prefix, key = id.split(CoolId.separator, 2)
|
63
|
-
model_class = @
|
63
|
+
model_class = @prefix_map[prefix]
|
64
64
|
return nil unless model_class
|
65
65
|
Id.new(key, prefix, id, model_class)
|
66
66
|
end
|
@@ -79,7 +79,7 @@ module CoolId
|
|
79
79
|
|
80
80
|
def validate_prefix(value)
|
81
81
|
raise ArgumentError, "Prefix cannot be nil" if value.nil?
|
82
|
-
raise ArgumentError, "Prefix cannot
|
82
|
+
raise ArgumentError, "Prefix cannot be empty" if value.empty?
|
83
83
|
value
|
84
84
|
end
|
85
85
|
|
@@ -94,7 +94,8 @@ module CoolId
|
|
94
94
|
extend ActiveSupport::Concern
|
95
95
|
|
96
96
|
class_methods do
|
97
|
-
|
97
|
+
attr_accessor :cool_id_config
|
98
|
+
attr_accessor :cool_id_setup_required
|
98
99
|
|
99
100
|
def cool_id(options)
|
100
101
|
@cool_id_config = Config.new(**options)
|
@@ -104,16 +105,38 @@ module CoolId
|
|
104
105
|
def generate_cool_id
|
105
106
|
CoolId.generate_id(@cool_id_config)
|
106
107
|
end
|
108
|
+
|
109
|
+
def enforce_cool_id_for_descendants
|
110
|
+
@cool_id_setup_required = true
|
111
|
+
end
|
112
|
+
|
113
|
+
def skip_enforce_cool_id_for_descendants
|
114
|
+
@cool_id_setup_required = false
|
115
|
+
end
|
116
|
+
|
117
|
+
def inherited(subclass)
|
118
|
+
super
|
119
|
+
if @cool_id_setup_required && !subclass.instance_variable_defined?(:@cool_id_setup_required)
|
120
|
+
subclass.instance_variable_set(:@cool_id_setup_required, true)
|
121
|
+
end
|
122
|
+
end
|
107
123
|
end
|
108
124
|
|
109
125
|
included do
|
110
126
|
before_create :set_cool_id
|
127
|
+
after_initialize :ensure_cool_id_configured
|
111
128
|
|
112
129
|
private
|
113
130
|
|
114
131
|
def set_cool_id
|
115
132
|
self.id = self.class.generate_cool_id if id.blank?
|
116
133
|
end
|
134
|
+
|
135
|
+
def ensure_cool_id_configured
|
136
|
+
if self.class.cool_id_setup_required && self.class.cool_id_config.nil?
|
137
|
+
raise Error, "CoolId not configured for #{self.class}. Use 'cool_id' to configure or 'skip_enforce_cool_id_for_descendants' to opt out."
|
138
|
+
end
|
139
|
+
end
|
117
140
|
end
|
118
141
|
end
|
119
142
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cool_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Schilling
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nanoid
|