rails-uuid-pk 0.4.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3eb01e2f1dc8ef76a90110c9d6ef882f79cfc6584395129046d404f116be94e3
4
- data.tar.gz: 7aa3b43c50beb54b037428f0abf36f4df642968eb0ba368bfe57328bcea2f8cf
3
+ metadata.gz: 93efad36dbc0fb3ab34a2a348a5dad4ae0cb75c3f6f62bf7da4580146fbcccb3
4
+ data.tar.gz: df2a8e217103e1c732c894fd4ab48333e149e8a42a1a92a08bb023d72673ffa3
5
5
  SHA512:
6
- metadata.gz: '09b2676618355ede8b113e7693e8c1673e1f8c32888f0027ab97fd82c81713af5b2f55b995d565f4445465c8c27ce53c4a42fe4f2247017e6c2cf4a0083af9e7'
7
- data.tar.gz: 967f36d838dfd8e649a8674cce0a29642f39ee0e1a45dc70c4f66a1597abf65591c71cb434d97fb21affccf337337a04f2602e9fe470d43a464f3b5c2eca2298
6
+ metadata.gz: '09577137b7dbdd2b488260130f6afd4473292d06fb6646e141176de11a425f243b95ae3c43b8e69e89a7fcf3cb6b72d3f6cdb3b9794b56bf884c05895e4822de'
7
+ data.tar.gz: 9a5818221c1251cb137e61a30045fb98a0957af248f9f3e5908e5e9fb6f8d74d4de84dfb60d40135d60028d4d679070c8d295174990f8cc990f58752841a33f0
data/CHANGELOG.md CHANGED
@@ -5,6 +5,38 @@ 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.6.0] - 2026-01-12
9
+
10
+ ### Added
11
+ - **Support for `add_reference` and `add_belongs_to`**: Migration helpers now automatically handle foreign key types for these methods as well.
12
+ - **Performance Caching**: Added primary key lookup caching during migrations to improve performance.
13
+
14
+ ### Changed
15
+ - **Improved Migration Helpers**: Enhanced robustness of foreign key type detection by handling more default types (`:bigint`, `:integer`, `nil`).
16
+ - **Refactored Railtie**: Unified UUID type registration for SQLite and MySQL, improving code maintainability.
17
+ - **Better Initialization**: Improved timing of adapter extensions using `ActiveSupport.on_load`.
18
+
19
+ ## [0.5.0] - 2026-01-10
20
+
21
+ ### Changed
22
+ - **Made gem truly zero-configuration**: Removed install generator and concern file
23
+ - Simplified installation to just `bundle install` - no generator command needed
24
+ - Removed `app/models/concerns/has_uuidv7_primary_key.rb` template and explicit inclusion option
25
+ - Updated documentation to reflect simplified zero-config approach
26
+ - All functionality now works automatically through Railtie inclusion
27
+
28
+ ### Removed
29
+ - Install generator (`rails g rails_uuid_pk:install`)
30
+ - Optional concern file for explicit inclusion
31
+ - Generator template and associated test cases
32
+ - Manual installation steps and configuration options
33
+
34
+ ### Technical Details
35
+ - Eliminated generator complexity while maintaining all core functionality
36
+ - Streamlined user experience - just add gem to Gemfile and it works
37
+ - Removed optional explicit concern inclusion in favor of automatic Railtie-based inclusion
38
+ - Updated AGENTS.md and README.md to reflect simplified architecture
39
+
8
40
  ## [0.4.0] - 2026-01-10
9
41
 
10
42
  ### Added
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # rails-uuid-pk
2
2
 
3
- **Dead-simple UUIDv7 primary keys for modern Rails apps**
4
- Works great with **PostgreSQL 18+**, **MySQL 8.0+**, and **SQLite 3.51+** — zero extra extensions required.
3
+ **Dead-simple UUIDv7 primary keys for modern Rails apps**
4
+
5
+ Automatically use UUID v7 for **all primary keys** in Rails applications. Works with PostgreSQL, MySQL, and SQLite — **zero configuration required**. Just add the gem and you're done!
5
6
 
6
7
  [![Gem Version](https://img.shields.io/gem/v/rails-uuid-pk.svg?style=flat-square)](https://rubygems.org/gems/rails-uuid-pk)
7
8
  [![Ruby](https://img.shields.io/badge/ruby-≥3.3-red.svg?style=flat-square)](https://www.ruby-lang.org)
@@ -24,21 +25,16 @@ Works great with **PostgreSQL 18+**, **MySQL 8.0+**, and **SQLite 3.51+** — ze
24
25
  Add to your `Gemfile`:
25
26
 
26
27
  ```ruby
27
- gem "rails-uuid-pk", "~> 0.3"
28
+ gem "rails-uuid-pk", "~> 0.6"
28
29
  ```
29
30
 
30
31
  Then run:
31
32
 
32
33
  ```bash
33
34
  bundle install
34
- rails generate rails_uuid_pk:install
35
35
  ```
36
36
 
37
- The generator will:
38
-
39
- - Set `primary_key_type: :uuid` in your generators config
40
- - Create `app/models/concerns/has_uuidv7_primary_key.rb` (optional explicit include)
41
- - Show important compatibility notes
37
+ That's it! The gem automatically enables UUIDv7 primary keys for all your models.
42
38
 
43
39
  ## Usage
44
40
 
@@ -60,32 +56,27 @@ User.create!(name: "Alice") # ← id is automatically a proper UUIDv7
60
56
 
61
57
  ### Action Text & Active Storage
62
58
 
63
- When you run:
59
+ When you install Action Text or Active Storage:
64
60
 
65
61
  ```bash
66
62
  rails action_text:install
67
63
  rails active_storage:install
68
64
  ```
69
65
 
70
- The generated migrations will **automatically use the correct foreign key types** when referencing tables with UUID primary keys. No manual editing required!
71
-
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.
66
+ The generated migrations seamlessly integrate with UUID primary keys. Rails-uuid-pk's smart migration helpers automatically detect UUID primary keys in referenced tables and set the appropriate `type: :uuid` for foreign keys.
73
67
 
74
68
  ### Polymorphic associations
75
69
 
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.
70
+ Polymorphic associations work seamlessly with UUID primary keys. Whether you're using Action Text's `record` references or custom polymorphic associations, the migration helpers automatically detect the parent table's primary key type and set the correct foreign key type.
77
71
 
78
- For **custom polymorphic associations**, the migration helpers will also automatically detect and set the correct type:
72
+ For example, this migration will automatically use `type: :uuid` when the parent models have UUID primary keys:
79
73
 
80
74
  ```ruby
81
- # This will automatically use type: :uuid if the parent models have UUID primary keys
82
75
  create_table :comments do |t|
83
76
  t.references :commentable, polymorphic: true
84
77
  end
85
78
  ```
86
79
 
87
- No manual `type: :uuid` specification needed!
88
-
89
80
  ## Features / Trade-offs
90
81
 
91
82
  | Feature | Status | Notes |
@@ -6,32 +6,51 @@ module RailsUuidPk
6
6
  ref_table = options.delete(:to_table) || ref_name.to_s.pluralize
7
7
 
8
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
9
+ # In Rails, default type is often passed as :integer or :bigint in the options hash
10
+ # depending on the Rails version and whether it is a migration or a table definition.
11
+ # We want to override it to :uuid if the target table uses UUID primary keys.
12
+ current_type = options[:type]
13
+ if (current_type.nil? || current_type == :integer || current_type == :bigint) &&
14
+ (uuid_primary_key?(ref_table) || (options[:polymorphic] && application_uses_uuid_primary_keys?))
12
15
  options[:type] = :uuid
13
16
  end
14
17
 
15
- super
18
+ super(*args, **options)
19
+ end
20
+
21
+ def add_reference(table_name, ref_name, **options)
22
+ ref_table = options.delete(:to_table) || ref_name.to_s.pluralize
23
+
24
+ current_type = options[:type]
25
+ if (current_type.nil? || current_type == :integer || current_type == :bigint) &&
26
+ (uuid_primary_key?(ref_table) || (options[:polymorphic] && application_uses_uuid_primary_keys?))
27
+ options[:type] = :uuid
28
+ end
29
+
30
+ super(table_name, ref_name, **options)
16
31
  end
17
32
 
18
33
  def application_uses_uuid_primary_keys?
19
34
  # Check if the application is configured to use UUID primary keys globally
20
- Rails.application.config.generators.options[:active_record]&.[](:primary_key_type) == :uuid
35
+ defined?(Rails) && Rails.application.config.generators.options[:active_record]&.[](:primary_key_type) == :uuid
21
36
  end
22
37
 
23
38
  alias_method :belongs_to, :references
39
+ alias_method :add_belongs_to, :add_reference
24
40
 
25
41
  private
26
42
 
27
43
  def uuid_primary_key?(table_name)
28
- conn = @conn || @base || (respond_to?(:connection) ? connection : nil)
29
- return false unless conn&.table_exists?(table_name)
44
+ # Cache results for the duration of the migration process to improve performance
45
+ @uuid_pk_cache ||= {}
46
+ return @uuid_pk_cache[table_name] if @uuid_pk_cache.key?(table_name)
30
47
 
31
- pk_column = find_primary_key_column(table_name, conn)
32
- return false unless pk_column
48
+ conn = @conn || @base || (respond_to?(:connection) ? connection : self)
49
+ # Ensure we have a connection-like object that can check for table existence
50
+ return false unless conn.respond_to?(:table_exists?) && conn.table_exists?(table_name)
33
51
 
34
- pk_column.sql_type.downcase.match?(/\A(uuid|varchar\(36\))\z/)
52
+ pk_column = find_primary_key_column(table_name, conn)
53
+ @uuid_pk_cache[table_name] = !!(pk_column && pk_column.sql_type.downcase.match?(/\A(uuid|varchar\(36\))\z/))
35
54
  end
36
55
 
37
56
  def find_primary_key_column(table_name, conn)
@@ -8,54 +8,31 @@ module RailsUuidPk
8
8
 
9
9
  initializer "rails-uuid-pk.configure_type_map", after: "active_record.initialize_database" do
10
10
  ActiveSupport.on_load(:active_record) do
11
- if ActiveRecord::Base.connection.adapter_name == "SQLite"
12
- # Register the UUID type with ActiveRecord
13
- ActiveRecord::Type.register(:uuid, RailsUuidPk::Type::Uuid, adapter: :sqlite3)
14
-
15
- # Map varchar SQL type to our custom UUID type (since that's how UUID columns are stored in SQLite)
16
- ActiveRecord::Base.connection.send(:type_map).register_type(/varchar/i) do |sql_type|
17
- RailsUuidPk::Type::Uuid.new
18
- end
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
-
33
- # Also map "uuid" SQL type to our custom UUID type for direct lookups
34
- ActiveRecord::Base.connection.send(:type_map).register_type "uuid" do |sql_type|
35
- RailsUuidPk::Type::Uuid.new
36
- end
11
+ adapter_name = ActiveRecord::Base.connection.adapter_name
12
+ if %w[SQLite MySQL].include?(adapter_name)
13
+ RailsUuidPk::Railtie.register_uuid_type(adapter_name.downcase.to_sym)
37
14
  end
38
15
  end
39
16
  end
40
17
 
41
18
  initializer "rails-uuid-pk.native_types" do
42
- require "active_record/connection_adapters/sqlite3_adapter"
43
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(RailsUuidPk::Sqlite3AdapterExtension)
44
- end
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
19
+ ActiveSupport.on_load(:active_record) do
20
+ case ActiveRecord::Base.connection.adapter_name
21
+ when "SQLite"
22
+ require "active_record/connection_adapters/sqlite3_adapter"
23
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(RailsUuidPk::Sqlite3AdapterExtension)
24
+ when "MySQL"
25
+ begin
26
+ require "active_record/connection_adapters/mysql2_adapter"
27
+ ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(RailsUuidPk::Mysql2AdapterExtension)
28
+ rescue LoadError
29
+ # MySQL adapter not available
30
+ end
31
+ end
52
32
  end
53
33
  end
54
34
 
55
-
56
-
57
35
  initializer "rails-uuid-pk.schema_format" do |app|
58
- # Ensure schema_format is set to :ruby for SQLite (default in Rails)
59
36
  app.config.active_record.schema_format ||= :ruby
60
37
  end
61
38
 
@@ -69,10 +46,21 @@ module RailsUuidPk
69
46
  ActiveSupport.on_load(:active_record) do
70
47
  require "rails_uuid_pk/migration_helpers"
71
48
 
72
- # Include migration helpers for all database adapters
73
49
  ActiveRecord::ConnectionAdapters::TableDefinition.prepend(RailsUuidPk::MigrationHelpers::References)
74
50
  ActiveRecord::ConnectionAdapters::Table.prepend(RailsUuidPk::MigrationHelpers::References)
51
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(RailsUuidPk::MigrationHelpers::References)
75
52
  end
76
53
  end
54
+
55
+ def self.register_uuid_type(adapter)
56
+ ActiveRecord::Type.register(:uuid, RailsUuidPk::Type::Uuid, adapter: adapter)
57
+
58
+ # Get the connection-specific type map
59
+ type_map = ActiveRecord::Base.connection.send(:type_map)
60
+ # Map varchar(36) or varchar SQL type to our custom UUID type
61
+ type_map.register_type(/varchar/i) { RailsUuidPk::Type::Uuid.new }
62
+ # Also map "uuid" SQL type for direct lookups
63
+ type_map.register_type("uuid") { RailsUuidPk::Type::Uuid.new }
64
+ end
77
65
  end
78
66
  end
@@ -1,3 +1,3 @@
1
1
  module RailsUuidPk
2
- VERSION = "0.4.0"
2
+ VERSION = "0.6.0"
3
3
  end
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.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joon Lee
@@ -77,9 +77,6 @@ files:
77
77
  - MIT-LICENSE
78
78
  - README.md
79
79
  - Rakefile
80
- - app/models/concerns/has_uuidv7_primary_key.rb
81
- - lib/generators/rails_uuid_pk/install/install_generator.rb
82
- - lib/generators/rails_uuid_pk/install/templates/has_uuidv7_primary_key.rb
83
80
  - lib/rails_uuid_pk.rb
84
81
  - lib/rails_uuid_pk/concern.rb
85
82
  - lib/rails_uuid_pk/migration_helpers.rb
@@ -1,17 +0,0 @@
1
- # app/models/concerns/has_uuidv7_primary_key.rb
2
- # (this file is copied by the generator - you can modify it later if needed)
3
-
4
- module HasUuidv7PrimaryKey
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- before_create :assign_uuidv7_if_needed, if: -> { id.nil? }
9
- end
10
-
11
- private
12
-
13
- def assign_uuidv7_if_needed
14
- return if id.present?
15
- self.id = SecureRandom.uuid_v7
16
- end
17
- end
@@ -1,42 +0,0 @@
1
- module RailsUuidPk
2
- module Generators
3
- class InstallGenerator < Rails::Generators::Base
4
- source_root File.expand_path("templates", __dir__)
5
-
6
- desc "Installs rails-uuid-pk: sets uuid primary key + includes UUIDv7 concern"
7
-
8
- def add_concern_file
9
- copy_file "has_uuidv7_primary_key.rb",
10
- "app/models/concerns/has_uuidv7_primary_key.rb"
11
- end
12
-
13
- def show_next_steps
14
- say "\nrails-uuid-pk was successfully installed!", :green
15
-
16
- say "\n✅ Action Text & Active Storage compatibility", :green
17
- say "─────────────────────────────────────────────────────────────"
18
- say "Migration helpers now automatically handle foreign key types!"
19
- say "When you run:"
20
- say " rails action_text:install"
21
- say " rails active_storage:install"
22
- say ""
23
- say "The generated migrations will automatically use the correct UUID types"
24
- say "for foreign keys. No manual editing required!"
25
- say "─────────────────────────────────────────────────────────────\n"
26
-
27
- say "\nRecommended next steps:", :yellow
28
- say " 1. Add to ApplicationRecord (if you prefer explicit include):"
29
- say " class ApplicationRecord < ActiveRecord::Base"
30
- say " primary_abstract_class"
31
- say " include HasUuidv7PrimaryKey"
32
- say " end\n"
33
-
34
- say " 2. Or keep relying on Railtie automatic include (recommended for most cases)\n"
35
-
36
- say " 3. Now you can run:", :cyan
37
- say " rails g model User name:string email:string\n"
38
- say " → will create table with uuid primary key + automatic uuidv7\n"
39
- end
40
- end
41
- end
42
- end
@@ -1,17 +0,0 @@
1
- # app/models/concerns/has_uuidv7_primary_key.rb
2
- # (this file is copied by the generator - you can modify it later if needed)
3
-
4
- module HasUuidv7PrimaryKey
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- before_create :assign_uuidv7_if_needed, if: -> { id.nil? }
9
- end
10
-
11
- private
12
-
13
- def assign_uuidv7_if_needed
14
- return if id.present?
15
- self.id = SecureRandom.uuid_v7
16
- end
17
- end