uuid_attribute 0.2.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +15 -14
- data/lib/uuid_attribute/railtie.rb +31 -29
- data/lib/uuid_attribute/utils.rb +3 -1
- data/lib/uuid_attribute/version.rb +1 -1
- data/lib/uuid_attribute.rb +1 -1
- data/test/config/config.rb +20 -0
- data/test/config/schema.rb +16 -0
- data/test/test_helper.rb +25 -0
- data/test/uuid/test_activerecord.rb +42 -0
- data/test/uuid/test_type.rb +6 -6
- metadata +15 -10
- data/lib/uuid_attribute/active_model.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e716f18577f556aa807d4ad19aa1f6cd62900f7ea5faab4ea3f88fb4cc8e3d5a
|
4
|
+
data.tar.gz: 22161c78f0e24c4117306db0c6d70b27665f911385ade24748d09619acefc657
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90698cabeeb889fc28c07ab0001e53575db198b611707dc0fb640348b32c2d9712f3c861ccfdbcfa3aceb56d8f85cb6255c3cae6a591697792b135140824ee7c
|
7
|
+
data.tar.gz: ef6d0daa754d19d805367b00646789b1813ea9db391bad35129ca9e06d67a165c3779047d1e227110b857a808b8a2499e767081316c381e92ff7e6e6befc5ce0
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,28 +1,35 @@
|
|
1
|
-
#
|
1
|
+
# UUidAttribute
|
2
2
|
|
3
3
|
## Installation
|
4
4
|
|
5
5
|
Install the gem and add to the application's Gemfile by executing:
|
6
6
|
|
7
|
-
$ bundle add
|
7
|
+
$ bundle add uuid_attribute
|
8
8
|
|
9
9
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
10
10
|
|
11
|
-
$ gem install
|
11
|
+
$ gem install uuid_attribute
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
|
-
TODO: Write usage instructions here
|
16
|
-
|
17
15
|
```
|
18
16
|
class YourModel < ApplicationRecord
|
19
|
-
# Need to put attribute manually
|
20
|
-
attribute :id, :uuid, default: -> { SecureRandom.uuid }
|
21
17
|
end
|
22
18
|
|
19
|
+
model = YourModel.create( ... )
|
20
|
+
YourModel:0x00007f85774135a8
|
21
|
+
id: "5iLEaLFZUeD6Dg8nnfSiCZ",
|
22
|
+
... >
|
23
|
+
|
24
|
+
Or if you want to disable auto detect of UUIDs
|
25
|
+
|
23
26
|
UuidAttribute.setup do |config|
|
24
27
|
# Configure generators to use UUID as primary key (defaults to true)
|
25
|
-
config.
|
28
|
+
config.auto_detect_binary_ids = false
|
29
|
+
end
|
30
|
+
|
31
|
+
class YourModel < ApplicationRecord
|
32
|
+
attribute :id, :uuid, default: -> { SecureRandom.uuid }
|
26
33
|
end
|
27
34
|
```
|
28
35
|
|
@@ -36,12 +43,6 @@ release a new version, update the version number in `version.rb`, and then run
|
|
36
43
|
git commits and the created tag, and push the `.gem` file to
|
37
44
|
[rubygems.org](https://rubygems.org).
|
38
45
|
|
39
|
-
## TODO
|
40
|
-
|
41
|
-
Write tests for each supported rails versions. See examples at:
|
42
|
-
https://github.com/rails/rails/tree/main/activerecord
|
43
|
-
https://github.com/heartcombo/simple_form/tree/main/gemfiles
|
44
|
-
|
45
46
|
## Contributing
|
46
47
|
|
47
48
|
Bug reports and pull requests are welcome on GitHub at
|
@@ -9,38 +9,21 @@ module UuidAttribute
|
|
9
9
|
config.eager_load_namespaces << ::UuidAttribute
|
10
10
|
|
11
11
|
class << self
|
12
|
-
def
|
13
|
-
field_info.type == :binary
|
12
|
+
def binary_structure?(field_info)
|
13
|
+
field_info.type == :binary
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def binary?(klass, field)
|
17
17
|
field_info = klass.attribute_types[field]
|
18
|
-
|
18
|
+
binary_structure?(field_info)
|
19
|
+
# && klass.method_defined?("#{field}?")
|
19
20
|
end
|
20
21
|
|
21
22
|
def valid_default_rails_ids?(att)
|
22
23
|
att.eql?("id") || att.end_with?("_id")
|
23
24
|
end
|
24
|
-
end
|
25
|
-
|
26
|
-
=begin
|
27
|
-
all_models = ObjectSpace.each_object(Class).select { |c| c < ApplicationRecord}.select(&:name)
|
28
|
-
all_models.each do |model|
|
29
|
-
puts model
|
30
|
-
model.attribute_names.each do |att|
|
31
|
-
next unless valid_default_rails_ids?(att) && binary16?(att)
|
32
|
-
|
33
|
-
default = nil
|
34
|
-
default = -> { SecureRandom.uuid } if att.eql? "id"
|
35
|
-
self.class.define_attribute att, ::UuidAttribute::UUID.new, default: default
|
36
|
-
end
|
37
|
-
end
|
38
|
-
=end
|
39
|
-
|
40
|
-
config.after_initialize do
|
41
|
-
ActiveRecord::Type.register(:uuid, ::UuidAttribute::UUID)
|
42
25
|
|
43
|
-
|
26
|
+
def list_models
|
44
27
|
models = []
|
45
28
|
Dir["#{Rails.root}/app/models/*"].each do |file|
|
46
29
|
model = File.basename(file, ".*").classify
|
@@ -49,23 +32,42 @@ end
|
|
49
32
|
|
50
33
|
models -= %w[ActiveRecord Concern]
|
51
34
|
|
52
|
-
models.each
|
53
|
-
|
35
|
+
models.each(&:constantize)
|
36
|
+
all_active_record_classes
|
37
|
+
end
|
38
|
+
|
39
|
+
def all_active_record_classes
|
40
|
+
ObjectSpace.each_object(Class).select { |c| c < ActiveRecord::Base }.select(&:name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def configure_binary_ids
|
44
|
+
list_models.each do |model|
|
54
45
|
model.attribute_names.each do |att|
|
55
|
-
next unless valid_default_rails_ids?(att) &&
|
46
|
+
next unless valid_default_rails_ids?(att) && binary?(model, att)
|
56
47
|
|
57
48
|
default = nil
|
58
49
|
default = -> { SecureRandom.uuid } if att.eql? "id"
|
59
|
-
model.
|
50
|
+
model.attribute att, ::UuidAttribute::UUID.new, default: default
|
60
51
|
end
|
61
52
|
end
|
53
|
+
rescue ActiveRecord::NoDatabaseError
|
54
|
+
puts "NO DATABASE"
|
55
|
+
false
|
56
|
+
else
|
57
|
+
puts "CONFIGURE BINARY"
|
58
|
+
true
|
62
59
|
end
|
60
|
+
end
|
61
|
+
|
62
|
+
config.after_initialize do
|
63
|
+
puts "REGISTERING UUID"
|
64
|
+
ActiveRecord::Type.register(:uuid, ::UuidAttribute::UUID)
|
63
65
|
|
64
|
-
|
66
|
+
configure_binary_ids if UuidAttribute.auto_detect_binary_ids
|
65
67
|
|
66
68
|
if UuidAttribute.default_primary_id
|
67
69
|
# Configure UUID as Default Primary Key
|
68
|
-
Rails
|
70
|
+
Rails&.application&.config&.generators do |g|
|
69
71
|
g.orm :active_record, primary_key_type: "binary, limit: 16"
|
70
72
|
end
|
71
73
|
end
|
data/lib/uuid_attribute/utils.rb
CHANGED
@@ -5,7 +5,7 @@ module UuidAttribute
|
|
5
5
|
class Utils
|
6
6
|
class << self
|
7
7
|
def normalize(uuid_string)
|
8
|
-
uuid_string
|
8
|
+
uuid_string&.gsub("-", "")&.upcase
|
9
9
|
end
|
10
10
|
|
11
11
|
def hex_from_binary(bytes)
|
@@ -23,6 +23,8 @@ module UuidAttribute
|
|
23
23
|
case str.length
|
24
24
|
when 32
|
25
25
|
format_uuid(str)
|
26
|
+
when 34
|
27
|
+
format_uuid(str)
|
26
28
|
when 16
|
27
29
|
format_uuid(hex_from_binary(str))
|
28
30
|
when 22
|
data/lib/uuid_attribute.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
require "active_model"
|
4
4
|
require "active_model/type"
|
5
|
+
require "rails"
|
5
6
|
require_relative "uuid_attribute/version"
|
6
7
|
require_relative "uuid_attribute/uuid"
|
7
|
-
require_relative "uuid_attribute/active_model"
|
8
8
|
require_relative "uuid_attribute/utils"
|
9
9
|
|
10
10
|
# UUID::Attribute is a module that provides a UUID attribute for ActiveRecord
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "pathname"
|
5
|
+
# require "active_support/configuration_file"
|
6
|
+
|
7
|
+
module ARTest
|
8
|
+
class << self
|
9
|
+
def config
|
10
|
+
@config ||= YAML.safe_load(File.read(config_file))
|
11
|
+
# ActiveSupport::ConfigurationFile.parse(config_file)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def config_file
|
17
|
+
Pathname.new(ENV["ARCONFIG"] || "#{TEST_ROOT}/config/config.yml")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define do
|
4
|
+
create_table "samples", id: :binary, limit: 16, force: :cascade do |t|
|
5
|
+
t.string "name"
|
6
|
+
t.datetime "created_at", null: false
|
7
|
+
t.datetime "updated_at", null: false
|
8
|
+
end
|
9
|
+
|
10
|
+
create_table "examples", id: :binary, limit: 16, force: :cascade do |t|
|
11
|
+
t.string "name"
|
12
|
+
t.references :sample, null: false, foreign_key: false, type: :binary, limit: 16
|
13
|
+
t.datetime "created_at", null: false
|
14
|
+
t.datetime "updated_at", null: false
|
15
|
+
end
|
16
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -8,5 +8,30 @@ SimpleCov.start "rails" do
|
|
8
8
|
add_filter "lib/uuid_attribute/version"
|
9
9
|
end
|
10
10
|
|
11
|
+
require "rails"
|
12
|
+
require "active_record"
|
11
13
|
require "minitest/autorun"
|
14
|
+
|
15
|
+
TEST_ROOT = __dir__
|
16
|
+
require "config/config"
|
17
|
+
puts "Testing with adapter #{ENV["TEST_ADAPTER"]} - Rails Version: #{Rails.version}"
|
18
|
+
|
19
|
+
# ActiveRecord.async_query_executor = :global_thread_pool if ActiveRecord.respond_to?(:async_query_executor)
|
20
|
+
ActiveRecord::Base.configurations = ARTest.config["connections"]
|
21
|
+
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
22
|
+
DATABASE_CONFIG = ActiveRecord::DatabaseConfigurations::HashConfig.new(
|
23
|
+
"test",
|
24
|
+
"test",
|
25
|
+
ARTest.config["connections"][ENV["TEST_ADAPTER"]]
|
26
|
+
) if Rails::VERSION::MAJOR >= 7 || (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR > 0)
|
27
|
+
DATABASE_CONFIG = ARTest.config["connections"][ENV["TEST_ADAPTER"]] if Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR == 0
|
28
|
+
ActiveRecord::Tasks::DatabaseTasks.purge(DATABASE_CONFIG) unless ENV["TEST_ADAPTER"] != "sqlite"
|
29
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(
|
30
|
+
DATABASE_CONFIG,
|
31
|
+
:ruby,
|
32
|
+
"#{TEST_ROOT}/config/schema.rb"
|
33
|
+
)
|
34
|
+
ActiveRecord::Base.establish_connection DATABASE_CONFIG
|
35
|
+
# load_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :no
|
36
|
+
|
12
37
|
require "uuid_attribute"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class Sample < ActiveRecord::Base
|
6
|
+
end
|
7
|
+
|
8
|
+
class Example < ActiveRecord::Base
|
9
|
+
belongs_to :sample
|
10
|
+
end
|
11
|
+
|
12
|
+
module UUID
|
13
|
+
class TestActiveRecord < Minitest::Test
|
14
|
+
def setup
|
15
|
+
UuidAttribute::Railtie.config.after_initialize.each do |block|
|
16
|
+
next unless block && block[0]
|
17
|
+
next unless block[0].source_location[0].include? "uuid_attribute/railtie.rb"
|
18
|
+
|
19
|
+
block[0].call
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_uuid_generation
|
24
|
+
result = Sample.new
|
25
|
+
refute_nil(result.id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_new_and_finds
|
29
|
+
result = Sample.create(name: "A Name")
|
30
|
+
assert(result.name, "A Name")
|
31
|
+
refute_nil(result.id)
|
32
|
+
assert(Sample.find(result.id).name, "A Name")
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_references
|
36
|
+
record_a = Sample.create(name: "Sample")
|
37
|
+
record_b = Example.create(name: "Example on Sample", sample: record_a)
|
38
|
+
assert(record_b.sample)
|
39
|
+
assert(record_b.sample.id, record_a.id)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/uuid/test_type.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require "test_helper"
|
3
4
|
require "active_record"
|
4
5
|
|
5
6
|
module UUID
|
6
7
|
class TestType < Minitest::Test
|
7
|
-
UNORMALIZED_UUID = "a0b1c2d3-e4f5-a6b7-c8d9-e0f1a2b3c4d5"
|
8
|
-
NORMALIZED_UUID = "A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5"
|
9
|
-
BINARY_UUID = "\xA0\xB1\xC2\xD3\xE4\xF5\xA6\xB7\xC8\xD9\xE0\xF1\xA2\xB3\xC4\xD5"
|
10
|
-
SHORTEN_UUID = "4tE0ZuelqYsF4p2FEnW2qb"
|
8
|
+
UNORMALIZED_UUID = "a0b1c2d3-e4f5-a6b7-c8d9-e0f1a2b3c4d5"
|
9
|
+
NORMALIZED_UUID = "A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5"
|
10
|
+
BINARY_UUID = "\xA0\xB1\xC2\xD3\xE4\xF5\xA6\xB7\xC8\xD9\xE0\xF1\xA2\xB3\xC4\xD5"
|
11
|
+
SHORTEN_UUID = "4tE0ZuelqYsF4p2FEnW2qb"
|
11
12
|
|
12
13
|
def test_type
|
13
|
-
assert_equal(::UuidAttribute::UUID.new.type
|
14
|
+
assert_equal(::UuidAttribute::UUID.new.type, :uuid)
|
14
15
|
end
|
15
16
|
|
16
17
|
def test_deserialize
|
@@ -26,7 +27,6 @@ module UUID
|
|
26
27
|
result = ::UuidAttribute::UUID.new.serialize(UNORMALIZED_UUID)
|
27
28
|
assert_equal("ActiveModel::Type::Binary::Data", result.class.name)
|
28
29
|
assert_equal(BINARY_UUID.bytes, result.to_s.bytes)
|
29
|
-
assert_equal(BINARY_UUID.bytes, [result.hex].pack("H*").bytes)
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_cast
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uuid_attribute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Negri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -49,24 +49,26 @@ files:
|
|
49
49
|
- LICENSE.md
|
50
50
|
- README.md
|
51
51
|
- lib/uuid_attribute.rb
|
52
|
-
- lib/uuid_attribute/active_model.rb
|
53
52
|
- lib/uuid_attribute/railtie.rb
|
54
53
|
- lib/uuid_attribute/utils.rb
|
55
54
|
- lib/uuid_attribute/uuid.rb
|
56
55
|
- lib/uuid_attribute/version.rb
|
56
|
+
- test/config/config.rb
|
57
|
+
- test/config/schema.rb
|
57
58
|
- test/test_helper.rb
|
59
|
+
- test/uuid/test_activerecord.rb
|
58
60
|
- test/uuid/test_configuration.rb
|
59
61
|
- test/uuid/test_type.rb
|
60
62
|
- test/uuid/test_utilities.rb
|
61
|
-
homepage: https://github.com/iugu/
|
63
|
+
homepage: https://github.com/iugu/uuid_attribute
|
62
64
|
licenses:
|
63
65
|
- MIT
|
64
66
|
metadata:
|
65
|
-
homepage_uri: https://github.com/iugu/
|
66
|
-
documentation_uri: https://
|
67
|
-
changelog_uri: https://github.com/iugu/
|
68
|
-
source_code_uri: https://github.com/iugu/
|
69
|
-
bug_tracker_uri: https://github.com/iugu/
|
67
|
+
homepage_uri: https://github.com/iugu/uuid_attribute
|
68
|
+
documentation_uri: https://github.com/iugu/uuid_attribute
|
69
|
+
changelog_uri: https://github.com/iugu/uuid_attribute/blob/main/CHANGELOG.md
|
70
|
+
source_code_uri: https://github.com/iugu/uuid_attribute
|
71
|
+
bug_tracker_uri: https://github.com/iugu/uuid_attribute/issues
|
70
72
|
post_install_message:
|
71
73
|
rdoc_options: []
|
72
74
|
require_paths:
|
@@ -75,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
77
|
requirements:
|
76
78
|
- - ">="
|
77
79
|
- !ruby/object:Gem::Version
|
78
|
-
version: 2.
|
80
|
+
version: 2.5.0
|
79
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
82
|
requirements:
|
81
83
|
- - ">="
|
@@ -87,7 +89,10 @@ signing_key:
|
|
87
89
|
specification_version: 4
|
88
90
|
summary: UUID attribute for ActiveRecord
|
89
91
|
test_files:
|
92
|
+
- test/config/config.rb
|
93
|
+
- test/config/schema.rb
|
90
94
|
- test/test_helper.rb
|
95
|
+
- test/uuid/test_activerecord.rb
|
91
96
|
- test/uuid/test_configuration.rb
|
92
97
|
- test/uuid/test_type.rb
|
93
98
|
- test/uuid/test_utilities.rb
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module UuidAttribute
|
4
|
-
# ActiveModel modifications
|
5
|
-
module ActiveModel
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
=begin
|
9
|
-
included do
|
10
|
-
alias_method :initialize_without_uuid, :initialize
|
11
|
-
alias_method :initialize, :uuid_initializer
|
12
|
-
end
|
13
|
-
|
14
|
-
def uuid_initializer(*args)
|
15
|
-
auto_detect_uuids
|
16
|
-
initialize_without_uuid(*args)
|
17
|
-
end
|
18
|
-
|
19
|
-
def binary16_structure?(field_info)
|
20
|
-
field_info.type == :binary && field_info.limit == 16
|
21
|
-
end
|
22
|
-
|
23
|
-
def binary16?(field)
|
24
|
-
field_info = self.class.attribute_types[field]
|
25
|
-
binary16_structure?(field_info) && respond_to?("#{field}?")
|
26
|
-
end
|
27
|
-
|
28
|
-
def valid_default_rails_ids?(att)
|
29
|
-
att.eql?("id") || att.end_with?("_id")
|
30
|
-
end
|
31
|
-
|
32
|
-
def auto_detect_uuids
|
33
|
-
return unless UuidAttribute.auto_detect_binary_ids
|
34
|
-
|
35
|
-
self.class.attribute_names.each do |att|
|
36
|
-
next unless valid_default_rails_ids?(att) && binary16?(att)
|
37
|
-
|
38
|
-
default = nil
|
39
|
-
default = -> { SecureRandom.uuid } if att.eql? "id"
|
40
|
-
self.class.define_attribute att, ::UuidAttribute::UUID.new, default: default
|
41
|
-
end
|
42
|
-
end
|
43
|
-
=end
|
44
|
-
end
|
45
|
-
end
|