From 710deb84f16689becef3ca9e324a0664ca47203c Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Fri, 3 May 2024 14:23:42 -0600 Subject: [PATCH] Define column methods on the ColumnMethods module The way they were being defined inside the `included` hook meant they ended up being defined directly on TableDefinition, contrary to the documentation: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html I left `define_column_methods` as a class method that gets extended onto TableDefinition, since there's at least one gem that relies on being able to call it there to define their own column types --- .../lib/active_record/connection_adapters.rb | 1 + .../abstract/schema_definitions.rb | 40 +++++++++---------- .../mysql/schema_definitions.rb | 9 ++--- .../postgresql/schema_definitions.rb | 11 +++-- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters.rb b/activerecord/lib/active_record/connection_adapters.rb index 96b7078825c6d..4a9a1837a1788 100644 --- a/activerecord/lib/active_record/connection_adapters.rb +++ b/activerecord/lib/active_record/connection_adapters.rb @@ -140,6 +140,7 @@ def resolve(adapter_name) # :nodoc: autoload_at "active_record/connection_adapters/abstract/schema_definitions" do autoload :IndexDefinition autoload :ColumnDefinition + autoload :ColumnMethods autoload :ChangeColumnDefinition autoload :ChangeColumnDefaultDefinition autoload :ForeignKeyDefinition diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 15f06d2419af4..453d8384fb86b 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -300,6 +300,22 @@ def foreign_table_name module ColumnMethods extend ActiveSupport::Concern + class_methods do + private + + def define_column_methods(*column_types) # :nodoc: + column_types.each do |column_type| + module_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{column_type}(*names, **options) + raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty? + names.each { |name| column(name, :#{column_type}, **options) } + end + RUBY + end + end + end + extend ClassMethods + # Appends a primary key definition to the table definition. # Can be called multiple times, but this is probably not a good idea. def primary_key(name, type = :primary_key, **options) @@ -317,27 +333,11 @@ def primary_key(name, type = :primary_key, **options) # # See TableDefinition#column - included do - define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal, - :float, :integer, :json, :string, :text, :time, :timestamp, :virtual + define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal, + :float, :integer, :json, :string, :text, :time, :timestamp, :virtual - alias :blob :binary - alias :numeric :decimal - end - - class_methods do - def define_column_methods(*column_types) # :nodoc: - column_types.each do |column_type| - module_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{column_type}(*names, **options) - raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty? - names.each { |name| column(name, :#{column_type}, **options) } - end - RUBY - end - end - private :define_column_methods - end + alias :blob :binary + alias :numeric :decimal end # = Active Record Connection Adapters \Table \Definition diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb index 33669cd7c2d41..909c361a25ede 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb @@ -5,6 +5,7 @@ module ConnectionAdapters module MySQL module ColumnMethods extend ActiveSupport::Concern + extend ConnectionAdapters::ColumnMethods::ClassMethods ## # :method: blob @@ -50,11 +51,9 @@ module ColumnMethods # :method: unsigned_decimal # :call-seq: unsigned_decimal(*names, **options) - included do - define_column_methods :blob, :tinyblob, :mediumblob, :longblob, - :tinytext, :mediumtext, :longtext, :unsigned_integer, :unsigned_bigint, - :unsigned_float, :unsigned_decimal - end + define_column_methods :blob, :tinyblob, :mediumblob, :longblob, + :tinytext, :mediumtext, :longtext, :unsigned_integer, :unsigned_bigint, + :unsigned_float, :unsigned_decimal end # = Active Record MySQL Adapter \Table Definition diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb index 97898d56b635e..b925e4d393baf 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb @@ -5,6 +5,7 @@ module ConnectionAdapters module PostgreSQL module ColumnMethods extend ActiveSupport::Concern + extend ConnectionAdapters::ColumnMethods::ClassMethods # Defines the primary key field. # Use of the native PostgreSQL UUID type is supported, and can be used @@ -181,12 +182,10 @@ def primary_key(name, type = :primary_key, **options) # :method: enum # :call-seq: enum(*names, **options) - included do - define_column_methods :bigserial, :bit, :bit_varying, :cidr, :citext, :daterange, - :hstore, :inet, :interval, :int4range, :int8range, :jsonb, :ltree, :macaddr, - :money, :numrange, :oid, :point, :line, :lseg, :box, :path, :polygon, :circle, - :serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml, :timestamptz, :enum - end + define_column_methods :bigserial, :bit, :bit_varying, :cidr, :citext, :daterange, + :hstore, :inet, :interval, :int4range, :int8range, :jsonb, :ltree, :macaddr, + :money, :numrange, :oid, :point, :line, :lseg, :box, :path, :polygon, :circle, + :serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml, :timestamptz, :enum end ExclusionConstraintDefinition = Struct.new(:table_name, :expression, :options) do