Problem
ActiveRecordRelations cannot generate an RBI for an Active Record model with a composite primary key. When generating ids, it passes
constant.primary_key—an Array—to ActiveRecordColumnTypeHelper#type_for, whose argument is typed as String.
Reproduced with Tapioca 0.19.2 and Rails 8. The same call is present in v0.20.0 and current main, though I have only run this reproduction against
0.19.2.
Minimal reproduction
With tapioca 0.19.2, Active Record 8, and the PostgreSQL adapter available, run bundle exec ruby repro.rb:
require "active_record"
require "active_record/connection_adapters/postgresql/oid/uuid"
require "tapioca/internal"
require "tapioca/dsl/compilers/active_record_relations"
class CompositeRecord < ActiveRecord::Base
self.primary_key = %w[listing_id checkin_on checkout_on]
def self.table_exists? = true
def self.columns_hash
%w[listing_id checkin_on checkout_on].to_h do |name|
[name, Struct.new(:null).new(false)]
end
end
def self.attribute_types
{
"listing_id" => ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Uuid.new,
"checkin_on" => ActiveRecord::Type::Date.new,
"checkout_on" => ActiveRecord::Type::Date.new,
}
end
end
compiler = Tapioca::Dsl::Compilers::ActiveRecordRelations
pipeline = Tapioca::Dsl::Pipeline.new(
requested_constants: [CompositeRecord],
requested_compilers: [compiler],
)
root = RBI::Tree.new
compiler.new(pipeline, root, CompositeRecord).decorate
The metadata is supplied in memory to keep the reproduction database-free; it exercises the actual compiler.
Actual result
TypeError: Parameter 'attribute_name': Expected type ::String,
got type Array with value ["listing_id", "checkin_on", "checkout_on"]
Caller: .../active_record_relations.rb:801
Definition: .../active_record_column_type_helper.rb:60
Expected result
Generation succeeds, with ids returning typed tuples for these columns—for example, T::Array[[::String, ::Date, ::Date]].
ActiveRecordColumnTypeHelper#type_for("id") already delegates to its composite-aware id_type method. Could the Relations compiler use that path for ids,
while preserving scalar/nonstandard primary-key behavior?
Related earlier work: #1966 addresses composite find overloads; #2007 addresses composite column types.
Problem
ActiveRecordRelationscannot generate an RBI for an Active Record model with a composite primary key. When generatingids, it passesconstant.primary_key—an Array—toActiveRecordColumnTypeHelper#type_for, whose argument is typed as String.Reproduced with Tapioca 0.19.2 and Rails 8. The same call is present in v0.20.0 and current main, though I have only run this reproduction against
0.19.2.
Minimal reproduction
With
tapioca0.19.2, Active Record 8, and the PostgreSQL adapter available, runbundle exec ruby repro.rb:The metadata is supplied in memory to keep the reproduction database-free; it exercises the actual compiler.
Actual result
Expected result
Generation succeeds, with ids returning typed tuples for these columns—for example, T::Array[[::String, ::Date, ::Date]].
ActiveRecordColumnTypeHelper#type_for("id") already delegates to its composite-aware id_type method. Could the Relations compiler use that path for ids,
while preserving scalar/nonstandard primary-key behavior?
Related earlier work: #1966 addresses composite find overloads; #2007 addresses composite column types.