rails-uuid-pk 0.2.0 → 0.4.0
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/CHANGELOG.md +41 -0
- data/README.md +26 -33
- data/lib/generators/rails_uuid_pk/install/install_generator.rb +5 -8
- data/lib/rails_uuid_pk/migration_helpers.rb +45 -0
- data/lib/rails_uuid_pk/mysql2_adapter_extension.rb +9 -0
- data/lib/rails_uuid_pk/railtie.rb +32 -0
- data/lib/rails_uuid_pk/version.rb +1 -1
- data/lib/rails_uuid_pk.rb +1 -0
- metadata +20 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3eb01e2f1dc8ef76a90110c9d6ef882f79cfc6584395129046d404f116be94e3
|
|
4
|
+
data.tar.gz: 7aa3b43c50beb54b037428f0abf36f4df642968eb0ba368bfe57328bcea2f8cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09b2676618355ede8b113e7693e8c1673e1f8c32888f0027ab97fd82c81713af5b2f55b995d565f4445465c8c27ce53c4a42fe4f2247017e6c2cf4a0083af9e7'
|
|
7
|
+
data.tar.gz: 967f36d838dfd8e649a8674cce0a29642f39ee0e1a45dc70c4f66a1597abf65591c71cb434d97fb21affccf337337a04f2602e9fe470d43a464f3b5c2eca2298
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v1.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0] - 2026-01-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **MySQL 8.0+ support**: Full MySQL compatibility with VARCHAR(36) UUID storage
|
|
12
|
+
- MySQL2 adapter extension for native database type mappings
|
|
13
|
+
- MySQL-specific type handling and schema dumping support
|
|
14
|
+
- Comprehensive MySQL test suite with performance and edge case testing
|
|
15
|
+
- CI pipeline support for MySQL 8.0 testing
|
|
16
|
+
- Updated documentation to include MySQL setup and compatibility notes
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Updated project description to reflect support for PostgreSQL, MySQL, and SQLite
|
|
20
|
+
- Enhanced test runner to support all three database adapters
|
|
21
|
+
- Updated development environment setup to include MySQL configuration
|
|
22
|
+
- Expanded database coverage from 2 to 3 major Rails database adapters
|
|
23
|
+
|
|
24
|
+
### Technical Details
|
|
25
|
+
- Added `lib/rails_uuid_pk/mysql2_adapter_extension.rb` for MySQL adapter integration
|
|
26
|
+
- Extended Railtie with MySQL-specific type mappings and adapter detection
|
|
27
|
+
- Enhanced migration helpers compatibility with MySQL VARCHAR(36) column detection
|
|
28
|
+
- Added MySQL performance testing (bulk operations, concurrent access, memory efficiency)
|
|
29
|
+
- Implemented MySQL edge case testing (long table names, special characters)
|
|
30
|
+
- Updated CI workflow with MySQL 8.0 service configuration
|
|
31
|
+
|
|
32
|
+
## [0.3.0] - 2026-01-09
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
- Migration helpers that automatically detect and set UUID foreign key types
|
|
36
|
+
- Smart `references` method that inspects database schema to determine primary key types
|
|
37
|
+
- Automatic UUID type assignment for polymorphic associations when using global UUID primary keys
|
|
38
|
+
- Comprehensive test coverage for migration helper functionality
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- Eliminated need for manual editing of Action Text and Active Storage migrations
|
|
42
|
+
- Updated install generator message to reflect automatic foreign key type handling
|
|
43
|
+
- Updated README.md to document the improved zero-config experience
|
|
44
|
+
- Changed "Zero config after install" status from "Yes (mostly)" to "Yes"
|
|
45
|
+
|
|
46
|
+
### Removed
|
|
47
|
+
- Manual migration editing requirement for Action Text & Active Storage compatibility
|
|
48
|
+
|
|
8
49
|
## [0.2.0] - 2026-01-07
|
|
9
50
|
|
|
10
51
|
### Added
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# rails-uuid-pk
|
|
2
2
|
|
|
3
3
|
**Dead-simple UUIDv7 primary keys for modern Rails apps**
|
|
4
|
-
Works great with **PostgreSQL 18
|
|
4
|
+
Works great with **PostgreSQL 18+**, **MySQL 8.0+**, and **SQLite 3.51+** — zero extra extensions required.
|
|
5
5
|
|
|
6
6
|
[](https://rubygems.org/gems/rails-uuid-pk)
|
|
7
7
|
[](https://www.ruby-lang.org)
|
|
@@ -12,7 +12,10 @@ Works great with **PostgreSQL 18+** and **SQLite 3.51+** — zero extra extensio
|
|
|
12
12
|
- Uses **native** `SecureRandom.uuid_v7` (Ruby 3.3+)
|
|
13
13
|
- Automatically sets `:uuid` as default primary key type
|
|
14
14
|
- Adds reliable `before_create` callback for UUIDv7 generation
|
|
15
|
-
- Works perfectly on **
|
|
15
|
+
- Works perfectly on **PostgreSQL 18+**, **MySQL 8.0+**, and **SQLite** (and older versions too)
|
|
16
|
+
- **PostgreSQL**: Uses native `UUID` column types with full database support
|
|
17
|
+
- **MySQL**: Uses `VARCHAR(36)` with custom ActiveRecord type handling
|
|
18
|
+
- **SQLite**: Uses `VARCHAR(36)` with custom ActiveRecord type handling
|
|
16
19
|
- Zero database extensions needed
|
|
17
20
|
- Minimal and maintainable — no monkey-patching hell
|
|
18
21
|
|
|
@@ -21,7 +24,7 @@ Works great with **PostgreSQL 18+** and **SQLite 3.51+** — zero extra extensio
|
|
|
21
24
|
Add to your `Gemfile`:
|
|
22
25
|
|
|
23
26
|
```ruby
|
|
24
|
-
gem "rails-uuid-pk", "~> 0.
|
|
27
|
+
gem "rails-uuid-pk", "~> 0.3"
|
|
25
28
|
```
|
|
26
29
|
|
|
27
30
|
Then run:
|
|
@@ -57,8 +60,6 @@ User.create!(name: "Alice") # ← id is automatically a proper UUIDv7
|
|
|
57
60
|
|
|
58
61
|
### Action Text & Active Storage
|
|
59
62
|
|
|
60
|
-
**These Rails engines do NOT automatically respect the `primary_key_type: :uuid` setting** when generating their install migrations.
|
|
61
|
-
|
|
62
63
|
When you run:
|
|
63
64
|
|
|
64
65
|
```bash
|
|
@@ -66,46 +67,36 @@ rails action_text:install
|
|
|
66
67
|
rails active_storage:install
|
|
67
68
|
```
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```ruby
|
|
72
|
-
t.references :record, null: false, polymorphic: true, index: false
|
|
73
|
-
# to
|
|
74
|
-
t.references :record, null: false, polymorphic: true, index: false, type: :uuid
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
Same applies to `active_storage_attachments.record_id`.
|
|
78
|
-
|
|
79
|
-
**Without this change** you will get:
|
|
70
|
+
The generated migrations will **automatically use the correct foreign key types** when referencing tables with UUID primary keys. No manual editing required!
|
|
80
71
|
|
|
81
|
-
- `
|
|
82
|
-
- Duplicate key violations on uniqueness indexes
|
|
83
|
-
- Association failures
|
|
72
|
+
This works because rails-uuid-pk includes smart migration helpers that detect the primary key type of referenced tables and automatically set `type: :uuid` for foreign keys.
|
|
84
73
|
|
|
85
|
-
|
|
86
|
-
The gem shows a big warning during installation — but double-check every time you install these engines.
|
|
74
|
+
### Polymorphic associations
|
|
87
75
|
|
|
88
|
-
|
|
76
|
+
**Polymorphic associations** (like Action Text's `record` references) will automatically use the correct foreign key type based on the referenced table's primary key. If the parent model uses UUID primary keys, the foreign key will be UUID type.
|
|
89
77
|
|
|
90
|
-
|
|
78
|
+
For **custom polymorphic associations**, the migration helpers will also automatically detect and set the correct type:
|
|
91
79
|
|
|
92
80
|
```ruby
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
has_many :comments, as: :commentable
|
|
81
|
+
# This will automatically use type: :uuid if the parent models have UUID primary keys
|
|
82
|
+
create_table :comments do |t|
|
|
83
|
+
t.references :commentable, polymorphic: true
|
|
84
|
+
end
|
|
98
85
|
```
|
|
99
86
|
|
|
87
|
+
No manual `type: :uuid` specification needed!
|
|
88
|
+
|
|
100
89
|
## Features / Trade-offs
|
|
101
90
|
|
|
102
91
|
| Feature | Status | Notes |
|
|
103
92
|
|--------------------------------------|-----------------|-----------------------------------------------------------------------|
|
|
104
93
|
| UUIDv7 generation | Automatic | Uses `SecureRandom.uuid_v7` (very good randomness + monotonicity) |
|
|
105
94
|
| PostgreSQL 18+ native `uuidv7()` | Not used | Fallback approach — more universal, no extensions needed |
|
|
106
|
-
|
|
|
95
|
+
| PostgreSQL support | Full | Native `UUID` column types with full database support |
|
|
96
|
+
| MySQL 8.0+ support | Full | Uses `VARCHAR(36)` with custom ActiveRecord type handling |
|
|
97
|
+
| SQLite support | Full | Uses `VARCHAR(36)` with custom ActiveRecord type handling |
|
|
107
98
|
| Index locality / performance | Very good | UUIDv7 is monotonic → almost as good as sequential IDs |
|
|
108
|
-
| Zero config after install | Yes
|
|
99
|
+
| Zero config after install | Yes | Migration helpers automatically handle foreign key types |
|
|
109
100
|
| Works with Rails 7.1 – 8+ | Yes | Tested conceptually up to Rails 8.1+ |
|
|
110
101
|
|
|
111
102
|
## Why not use native PostgreSQL `uuidv7()`?
|
|
@@ -131,15 +122,16 @@ This project includes a devcontainer configuration for VS Code. To get started:
|
|
|
131
122
|
|
|
132
123
|
### Running Tests
|
|
133
124
|
|
|
134
|
-
The project includes a comprehensive test suite that runs against
|
|
125
|
+
The project includes a comprehensive test suite that runs against SQLite, PostgreSQL, and MySQL.
|
|
135
126
|
|
|
136
127
|
```bash
|
|
137
|
-
# Run all tests (SQLite + PostgreSQL)
|
|
128
|
+
# Run all tests (SQLite + PostgreSQL + MySQL)
|
|
138
129
|
./bin/test
|
|
139
130
|
|
|
140
131
|
# Run tests for specific database
|
|
141
132
|
DB=sqlite ./bin/test # SQLite only
|
|
142
133
|
DB=postgres ./bin/test # PostgreSQL only
|
|
134
|
+
DB=mysql ./bin/test # MySQL only
|
|
143
135
|
```
|
|
144
136
|
|
|
145
137
|
### Code Quality
|
|
@@ -164,9 +156,10 @@ gem install rails-uuid-pk-0.1.0.gem
|
|
|
164
156
|
|
|
165
157
|
### Database Setup
|
|
166
158
|
|
|
167
|
-
For
|
|
159
|
+
For database testing, ensure the respective databases are running and accessible. The test suite uses these environment variables:
|
|
168
160
|
- `DB_HOST` (defaults to localhost)
|
|
169
161
|
- `RAILS_ENV=test_postgresql` for PostgreSQL tests
|
|
162
|
+
- `RAILS_ENV=test_mysql` for MySQL tests
|
|
170
163
|
|
|
171
164
|
## Contributing
|
|
172
165
|
|
|
@@ -13,18 +13,15 @@ module RailsUuidPk
|
|
|
13
13
|
def show_next_steps
|
|
14
14
|
say "\nrails-uuid-pk was successfully installed!", :green
|
|
15
15
|
|
|
16
|
-
say "\n
|
|
16
|
+
say "\n✅ Action Text & Active Storage compatibility", :green
|
|
17
17
|
say "─────────────────────────────────────────────────────────────"
|
|
18
|
-
say "
|
|
18
|
+
say "Migration helpers now automatically handle foreign key types!"
|
|
19
|
+
say "When you run:"
|
|
19
20
|
say " rails action_text:install"
|
|
20
21
|
say " rails active_storage:install"
|
|
21
22
|
say ""
|
|
22
|
-
say "
|
|
23
|
-
say ""
|
|
24
|
-
say " t.references :record, null: false, polymorphic: true, index: false, type: :uuid"
|
|
25
|
-
say ""
|
|
26
|
-
say "Without this change you'll get type mismatch errors (bigint vs uuid)."
|
|
27
|
-
say "This is a Rails limitation - see Rails guides for details."
|
|
23
|
+
say "The generated migrations will automatically use the correct UUID types"
|
|
24
|
+
say "for foreign keys. No manual editing required!"
|
|
28
25
|
say "─────────────────────────────────────────────────────────────\n"
|
|
29
26
|
|
|
30
27
|
say "\nRecommended next steps:", :yellow
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module RailsUuidPk
|
|
2
|
+
module MigrationHelpers
|
|
3
|
+
module References
|
|
4
|
+
def references(*args, **options)
|
|
5
|
+
ref_name = args.first
|
|
6
|
+
ref_table = options.delete(:to_table) || ref_name.to_s.pluralize
|
|
7
|
+
|
|
8
|
+
# Only set UUID type if not already explicitly set by user
|
|
9
|
+
# Rails sets type: :integer by default, so we override that
|
|
10
|
+
# But if user explicitly set a different type, we respect it
|
|
11
|
+
if (uuid_primary_key?(ref_table) || (options[:polymorphic] && application_uses_uuid_primary_keys?)) && options[:type] == :integer
|
|
12
|
+
options[:type] = :uuid
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def application_uses_uuid_primary_keys?
|
|
19
|
+
# Check if the application is configured to use UUID primary keys globally
|
|
20
|
+
Rails.application.config.generators.options[:active_record]&.[](:primary_key_type) == :uuid
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
alias_method :belongs_to, :references
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def uuid_primary_key?(table_name)
|
|
28
|
+
conn = @conn || @base || (respond_to?(:connection) ? connection : nil)
|
|
29
|
+
return false unless conn&.table_exists?(table_name)
|
|
30
|
+
|
|
31
|
+
pk_column = find_primary_key_column(table_name, conn)
|
|
32
|
+
return false unless pk_column
|
|
33
|
+
|
|
34
|
+
pk_column.sql_type.downcase.match?(/\A(uuid|varchar\(36\))\z/)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def find_primary_key_column(table_name, conn)
|
|
38
|
+
pk_name = conn.primary_key(table_name)
|
|
39
|
+
return nil unless pk_name
|
|
40
|
+
|
|
41
|
+
conn.columns(table_name).find { |c| c.name == pk_name }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -17,6 +17,19 @@ module RailsUuidPk
|
|
|
17
17
|
RailsUuidPk::Type::Uuid.new
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Also map "uuid" SQL type to our custom UUID type for direct lookups
|
|
21
|
+
ActiveRecord::Base.connection.send(:type_map).register_type "uuid" do |sql_type|
|
|
22
|
+
RailsUuidPk::Type::Uuid.new
|
|
23
|
+
end
|
|
24
|
+
elsif ActiveRecord::Base.connection.adapter_name == "MySQL"
|
|
25
|
+
# Register the UUID type with ActiveRecord for MySQL
|
|
26
|
+
ActiveRecord::Type.register(:uuid, RailsUuidPk::Type::Uuid, adapter: :mysql2)
|
|
27
|
+
|
|
28
|
+
# Map varchar SQL type to our custom UUID type (since that's how UUID columns are stored in MySQL)
|
|
29
|
+
ActiveRecord::Base.connection.send(:type_map).register_type(/varchar/i) do |sql_type|
|
|
30
|
+
RailsUuidPk::Type::Uuid.new
|
|
31
|
+
end
|
|
32
|
+
|
|
20
33
|
# Also map "uuid" SQL type to our custom UUID type for direct lookups
|
|
21
34
|
ActiveRecord::Base.connection.send(:type_map).register_type "uuid" do |sql_type|
|
|
22
35
|
RailsUuidPk::Type::Uuid.new
|
|
@@ -30,6 +43,15 @@ module RailsUuidPk
|
|
|
30
43
|
ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(RailsUuidPk::Sqlite3AdapterExtension)
|
|
31
44
|
end
|
|
32
45
|
|
|
46
|
+
initializer "rails-uuid-pk.mysql_native_types" do
|
|
47
|
+
begin
|
|
48
|
+
require "active_record/connection_adapters/mysql2_adapter"
|
|
49
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(RailsUuidPk::Mysql2AdapterExtension)
|
|
50
|
+
rescue LoadError
|
|
51
|
+
# MySQL adapter not available, skip MySQL-specific initialization
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
33
55
|
|
|
34
56
|
|
|
35
57
|
initializer "rails-uuid-pk.schema_format" do |app|
|
|
@@ -42,5 +64,15 @@ module RailsUuidPk
|
|
|
42
64
|
ActiveRecord::Base.include RailsUuidPk::HasUuidv7PrimaryKey
|
|
43
65
|
end
|
|
44
66
|
end
|
|
67
|
+
|
|
68
|
+
initializer "rails-uuid-pk.migration_helpers" do
|
|
69
|
+
ActiveSupport.on_load(:active_record) do
|
|
70
|
+
require "rails_uuid_pk/migration_helpers"
|
|
71
|
+
|
|
72
|
+
# Include migration helpers for all database adapters
|
|
73
|
+
ActiveRecord::ConnectionAdapters::TableDefinition.prepend(RailsUuidPk::MigrationHelpers::References)
|
|
74
|
+
ActiveRecord::ConnectionAdapters::Table.prepend(RailsUuidPk::MigrationHelpers::References)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
45
77
|
end
|
|
46
78
|
end
|
data/lib/rails_uuid_pk.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-uuid-pk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joon Lee
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '8.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mysql2
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.5.7
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.5.7
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: pg
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -51,8 +65,8 @@ dependencies:
|
|
|
51
65
|
- - "~>"
|
|
52
66
|
- !ruby/object:Gem::Version
|
|
53
67
|
version: 2.9.0
|
|
54
|
-
description: Automatically use
|
|
55
|
-
Works with PostgreSQL and SQLite, zero configuration required.
|
|
68
|
+
description: Automatically use UUID v7 for all primary keys in Rails applications.
|
|
69
|
+
Works with PostgreSQL, MySQL, and SQLite, zero configuration required.
|
|
56
70
|
email:
|
|
57
71
|
- seouri@gmail.com
|
|
58
72
|
executables: []
|
|
@@ -68,6 +82,8 @@ files:
|
|
|
68
82
|
- lib/generators/rails_uuid_pk/install/templates/has_uuidv7_primary_key.rb
|
|
69
83
|
- lib/rails_uuid_pk.rb
|
|
70
84
|
- lib/rails_uuid_pk/concern.rb
|
|
85
|
+
- lib/rails_uuid_pk/migration_helpers.rb
|
|
86
|
+
- lib/rails_uuid_pk/mysql2_adapter_extension.rb
|
|
71
87
|
- lib/rails_uuid_pk/railtie.rb
|
|
72
88
|
- lib/rails_uuid_pk/sqlite3_adapter_extension.rb
|
|
73
89
|
- lib/rails_uuid_pk/type.rb
|
|
@@ -96,5 +112,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
96
112
|
requirements: []
|
|
97
113
|
rubygems_version: 4.0.3
|
|
98
114
|
specification_version: 4
|
|
99
|
-
summary: Dead-simple
|
|
115
|
+
summary: Dead-simple UUID v7 primary keys for Rails apps
|
|
100
116
|
test_files: []
|