typed_uuid 2.3 → 3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -6
- data/lib/typed_uuid/active_record.rb +77 -51
- data/lib/typed_uuid/railtie.rb +1 -1
- data/lib/typed_uuid/version.rb +1 -1
- data/test/test_helper.rb +14 -9
- data/test/typed_uuid_test.rb +35 -5
- 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: 43aee2470b269097c2a79848c41aaa7e2dc490b097ed0ec38e5c5dba2cc46fb1
|
4
|
+
data.tar.gz: de4d70c9c051f43d14acf0f1c32b4f5e9428038e68c28e63cf41593a38294f7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df59f77e9cad353ade579c091532197fcc4363dba10ab2c4914c3379d839648a0c1d56bea3f42925189e6bbc9996bb98894dbe625749950a817e099c2503db37
|
7
|
+
data.tar.gz: 0a047a6fed326adb9880d92138cc390faf7670fa60319b219725998fec3a15b42be239f05934e2d4a4bfd3ad0dfea43aa33c24a01030df79a62130c9ac04d81c
|
data/README.md
CHANGED
@@ -33,24 +33,27 @@ Add this to your Gemfile:
|
|
33
33
|
`gem 'typed_uuid'`
|
34
34
|
|
35
35
|
Once bundled you can add an initializer to Rails to register your types as shown
|
36
|
-
below. This maps the
|
36
|
+
below. This maps the __Model Classes__ to an integer between 0 and 65,535.
|
37
37
|
|
38
38
|
```ruby
|
39
39
|
# config/initializers/uuid_types.rb
|
40
40
|
|
41
41
|
ActiveRecord::Base.register_uuid_types({
|
42
|
-
|
43
|
-
|
42
|
+
Listing: 0,
|
43
|
+
Building: 512,
|
44
|
+
'Building::SkyScrpaer' => 65_535
|
44
45
|
})
|
45
46
|
|
46
47
|
# Or:
|
47
48
|
|
48
49
|
ActiveRecord::Base.register_uuid_types({
|
49
|
-
0
|
50
|
-
|
50
|
+
0 => :Listing,
|
51
|
+
512 => :Building,
|
52
|
+
65_535 => 'Building::SkyScrpaer'
|
51
53
|
})
|
52
54
|
```
|
53
55
|
|
56
|
+
|
54
57
|
## Usage
|
55
58
|
|
56
59
|
In your migrations simply replace `id: :uuid` with `id: :typed_uuid` when creating
|
@@ -64,4 +67,12 @@ class CreateProperties < ActiveRecord::Migration[5.2]
|
|
64
67
|
end
|
65
68
|
end
|
66
69
|
end
|
67
|
-
```
|
70
|
+
```
|
71
|
+
|
72
|
+
## STI Models
|
73
|
+
When using STI Model Rails will generate the UUID to be inserted. This UUID will
|
74
|
+
be calculated of the STI Model class and not the base class.
|
75
|
+
|
76
|
+
In the migration you can still used `id: :typed_uuid`, this will use the base
|
77
|
+
class to calculated the default type for the UUID. You could also set the
|
78
|
+
`id` to `:uuid` and the `default` to `false` so when no ID is given it will error.
|
@@ -1,79 +1,105 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
1
3
|
module TypedUUID::ActiveRecord
|
4
|
+
extend ActiveSupport::Concern
|
2
5
|
|
3
6
|
UUID_TYPE_CONFLICT_MESSAGE = \
|
4
|
-
"You tried to define an UUID type %{int} for \"%{
|
7
|
+
"You tried to define an UUID type %{int} for \"%{class_name}\", but " \
|
5
8
|
" %{int} is already defined as the type for %{other}"
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
|
10
|
+
included do
|
11
|
+
class_attribute(:defined_uuid_types, instance_writer: false, default: {})
|
12
|
+
class_attribute(:uuid_type_cache, instance_writer: false, default: {})
|
10
13
|
end
|
11
14
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
int: int,
|
18
|
-
table: table,
|
19
|
-
other: defined_uuid_types[int]
|
20
|
-
}
|
21
|
-
else
|
22
|
-
defined_uuid_types[int] = table.to_s
|
15
|
+
def _create_record
|
16
|
+
klass = self.class
|
17
|
+
if !klass.descends_from_active_record? && klass.typed?
|
18
|
+
pk = klass.primary_key
|
19
|
+
write_attribute(pk, klass.typed_uuid) if pk && read_attribute(pk).nil?
|
23
20
|
end
|
21
|
+
|
22
|
+
super
|
24
23
|
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
if
|
29
|
-
|
25
|
+
class_methods do
|
26
|
+
def register_uuid_type(class_name, int)
|
27
|
+
if int < 0 || int > 65_535
|
28
|
+
raise ArgumentError, "UUID type must be between 0 and 65,535"
|
29
|
+
elsif defined_uuid_types.has_key?(int)
|
30
|
+
raise ArgumentError, UUID_TYPE_CONFLICT_MESSAGE % {
|
31
|
+
int: int,
|
32
|
+
class_name: class_name,
|
33
|
+
other: defined_uuid_types[int]
|
34
|
+
}
|
30
35
|
else
|
31
|
-
|
36
|
+
defined_uuid_types[int] = class_name.to_s
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def register_uuid_types(mapping)
|
41
|
+
mapping.each do |k, v|
|
42
|
+
if k.is_a?(Integer)
|
43
|
+
register_uuid_type(v, k)
|
44
|
+
else
|
45
|
+
register_uuid_type(k, v)
|
46
|
+
end
|
32
47
|
end
|
33
48
|
end
|
34
|
-
end
|
35
49
|
|
36
|
-
|
37
|
-
|
38
|
-
|
50
|
+
def typed?
|
51
|
+
!!defined_uuid_types.key(self.base_class.name)
|
52
|
+
end
|
53
|
+
|
54
|
+
def typed_uuid
|
55
|
+
TypedUUID.uuid(uuid_type_from_class(self))
|
56
|
+
end
|
39
57
|
|
40
|
-
|
41
|
-
|
42
|
-
if type.nil?
|
43
|
-
raise ArgumentError, "UUID Type for \"#{table}\" not defined"
|
58
|
+
def uuid_type_from_table_name(table)
|
59
|
+
uuid_type_from_class(class_from_table_name(table))
|
44
60
|
end
|
61
|
+
|
62
|
+
def uuid_type_from_class(klass)
|
63
|
+
type = defined_uuid_types.key(klass.name)
|
64
|
+
|
65
|
+
if type.nil?
|
66
|
+
raise ArgumentError, "UUID Type for \"#{klass.name}\" not defined"
|
67
|
+
end
|
45
68
|
|
46
|
-
|
47
|
-
|
69
|
+
type
|
70
|
+
end
|
71
|
+
|
72
|
+
def class_from_uuid_type(type)
|
73
|
+
if klass = uuid_type_cache[type]
|
74
|
+
return klass
|
75
|
+
else
|
76
|
+
Rails.application.eager_load! if !Rails.application.config.eager_load
|
48
77
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
78
|
+
::ActiveRecord::Base.descendants.each do |klass|
|
79
|
+
next if klass.table_name.nil?
|
80
|
+
|
81
|
+
uuid_type_cache[defined_uuid_types.key(klass.name)] = klass
|
82
|
+
end
|
83
|
+
|
84
|
+
uuid_type_cache[type]
|
85
|
+
end
|
53
86
|
end
|
54
|
-
|
55
|
-
type
|
56
|
-
end
|
57
87
|
|
58
|
-
|
59
|
-
|
60
|
-
return klass
|
61
|
-
else
|
88
|
+
def class_from_table_name(table)
|
89
|
+
table = table.to_s
|
62
90
|
Rails.application.eager_load! if !Rails.application.config.eager_load
|
63
|
-
|
64
|
-
::ActiveRecord::Base.descendants.
|
91
|
+
|
92
|
+
::ActiveRecord::Base.descendants.find do |klass|
|
65
93
|
next unless ( klass.superclass == ::ActiveRecord::Base || klass.superclass.abstract_class? )
|
66
94
|
next if klass.table_name.nil?
|
67
|
-
|
68
|
-
|
95
|
+
|
96
|
+
klass.table_name == table
|
69
97
|
end
|
70
|
-
|
71
|
-
uuid_type_cache[type]
|
72
98
|
end
|
73
|
-
end
|
74
99
|
|
75
|
-
|
76
|
-
|
100
|
+
def class_from_uuid(uuid)
|
101
|
+
class_from_uuid_type(TypedUUID.enum(uuid))
|
102
|
+
end
|
77
103
|
end
|
78
104
|
|
79
105
|
end
|
data/lib/typed_uuid/railtie.rb
CHANGED
@@ -4,7 +4,7 @@ class TypedUUID::Railtie < Rails::Railtie
|
|
4
4
|
ActiveRecord::Tasks::DatabaseTasks.migrations_paths << File.expand_path('../../../db/migrate', __FILE__)
|
5
5
|
|
6
6
|
ActiveSupport.on_load(:active_record) do
|
7
|
-
ActiveRecord::Base.
|
7
|
+
ActiveRecord::Base.include TypedUUID::ActiveRecord
|
8
8
|
end
|
9
9
|
|
10
10
|
require 'active_record/connection_adapters/postgresql/schema_definitions'
|
data/lib/typed_uuid/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -28,7 +28,9 @@ module ActiveRecord::Tasks::DatabaseTasks
|
|
28
28
|
end
|
29
29
|
TypedUUID::Railtie.initializers.each(&:run)
|
30
30
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
31
|
-
|
31
|
+
def MiniTest.filter_backtrace(bt)
|
32
|
+
bt
|
33
|
+
end
|
32
34
|
class ActiveSupport::TestCase
|
33
35
|
|
34
36
|
# File 'lib/active_support/testing/declarative.rb'
|
@@ -52,6 +54,9 @@ class ActiveSupport::TestCase
|
|
52
54
|
set_callback(:setup, :before) do
|
53
55
|
Rails.stubs(:application).returns(stub(config: stub(eager_load: true)))
|
54
56
|
if !self.class.class_variable_defined?(:@@suite_setup_run)
|
57
|
+
ActiveRecord::Base.defined_uuid_types = {}
|
58
|
+
ActiveRecord::Base.uuid_type_cache = {}
|
59
|
+
|
55
60
|
configuration = {
|
56
61
|
adapter: "postgresql",
|
57
62
|
database: "uuid-types-test",
|
@@ -76,14 +81,14 @@ class ActiveSupport::TestCase
|
|
76
81
|
self.class.class_variable_set(:@@suite_setup_run, true)
|
77
82
|
end
|
78
83
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
def debug
|
85
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
86
|
+
$debugging = true
|
87
|
+
yield
|
88
|
+
ensure
|
89
|
+
ActiveRecord::Base.logger = nil
|
90
|
+
$debugging = false
|
91
|
+
end
|
87
92
|
|
88
93
|
def capture_sql
|
89
94
|
# ActiveRecord::Base.connection.materialize_transactions
|
data/test/typed_uuid_test.rb
CHANGED
@@ -4,8 +4,9 @@ class FilterTest < ActiveSupport::TestCase
|
|
4
4
|
|
5
5
|
schema do
|
6
6
|
ActiveRecord::Base.register_uuid_types({
|
7
|
-
|
8
|
-
|
7
|
+
'FilterTest::Listing' => 0,
|
8
|
+
'FilterTest::Building' => 592,
|
9
|
+
'FilterTest::SkyScraper' => 1_952
|
9
10
|
})
|
10
11
|
|
11
12
|
create_table :listings, id: :typed_uuid do |t|
|
@@ -14,6 +15,7 @@ class FilterTest < ActiveSupport::TestCase
|
|
14
15
|
|
15
16
|
create_table :buildings, id: :typed_uuid do |t|
|
16
17
|
t.string "name", limit: 255
|
18
|
+
t.string "type", limit: 255
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
@@ -22,10 +24,19 @@ class FilterTest < ActiveSupport::TestCase
|
|
22
24
|
|
23
25
|
class Building < ActiveRecord::Base
|
24
26
|
end
|
27
|
+
|
28
|
+
class SkyScraper < Building
|
29
|
+
end
|
25
30
|
|
31
|
+
class SingleFamilyHome < Building
|
32
|
+
end
|
33
|
+
|
34
|
+
class Property < ActiveRecord::Base
|
35
|
+
end
|
36
|
+
|
26
37
|
test 'adding primary key as a typed_uuid in a migration' do
|
27
38
|
ActiveRecord::Base.register_uuid_types({
|
28
|
-
|
39
|
+
1 => 'FilterTest::Property'
|
29
40
|
})
|
30
41
|
|
31
42
|
exprexted_sql = <<-SQL
|
@@ -43,16 +54,27 @@ class FilterTest < ActiveSupport::TestCase
|
|
43
54
|
|
44
55
|
test 'typed_uuid' do
|
45
56
|
assert_equal 512, TypedUUID.enum(TypedUUID.uuid(512))
|
46
|
-
assert_equal FilterTest::Listing,
|
47
|
-
assert_equal FilterTest::Building,
|
57
|
+
assert_equal FilterTest::Listing, ::ActiveRecord::Base.class_from_uuid(Listing.typed_uuid)
|
58
|
+
assert_equal FilterTest::Building, ::ActiveRecord::Base.class_from_uuid(Building.typed_uuid)
|
59
|
+
assert_equal FilterTest::SkyScraper, ::ActiveRecord::Base.class_from_uuid(SkyScraper.typed_uuid)
|
60
|
+
|
61
|
+
assert_raises ArgumentError do
|
62
|
+
::ActiveRecord::Base.class_from_uuid(SingleFamilyHome.typed_uuid)
|
63
|
+
end
|
48
64
|
end
|
49
65
|
|
50
66
|
test 'class_from uuid' do
|
51
67
|
listing = Listing.create
|
52
68
|
building = Building.create
|
69
|
+
skyscraper = SkyScraper.create
|
53
70
|
|
54
71
|
assert_equal FilterTest::Listing, ::ActiveRecord::Base.class_from_uuid(listing.id)
|
55
72
|
assert_equal FilterTest::Building, ::ActiveRecord::Base.class_from_uuid(building.id)
|
73
|
+
assert_equal FilterTest::SkyScraper, ::ActiveRecord::Base.class_from_uuid(skyscraper.id)
|
74
|
+
|
75
|
+
assert_raises ArgumentError do
|
76
|
+
SingleFamilyHome.create
|
77
|
+
end
|
56
78
|
end
|
57
79
|
|
58
80
|
test 'uuid_type from table_name' do
|
@@ -61,9 +83,17 @@ class FilterTest < ActiveSupport::TestCase
|
|
61
83
|
assert_equal 592, ::ActiveRecord::Base.uuid_type_from_table_name(:buildings)
|
62
84
|
end
|
63
85
|
|
86
|
+
test 'uuid_type from class' do
|
87
|
+
assert_equal 0, ::ActiveRecord::Base.uuid_type_from_class(Listing)
|
88
|
+
assert_equal 0, ::ActiveRecord::Base.uuid_type_from_class(Listing)
|
89
|
+
assert_equal 592, ::ActiveRecord::Base.uuid_type_from_class(Building)
|
90
|
+
assert_equal 1_952, ::ActiveRecord::Base.uuid_type_from_class(SkyScraper)
|
91
|
+
end
|
92
|
+
|
64
93
|
test 'class from uuid_type' do
|
65
94
|
assert_equal FilterTest::Listing, ::ActiveRecord::Base.class_from_uuid_type(0)
|
66
95
|
assert_equal FilterTest::Building, ::ActiveRecord::Base.class_from_uuid_type(592)
|
96
|
+
assert_equal FilterTest::SkyScraper, ::ActiveRecord::Base.class_from_uuid_type(1_952)
|
67
97
|
end
|
68
98
|
|
69
99
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typed_uuid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '3.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|