activerecord-cockroachdb-adapter
activerecord-cockroachdb-adapter copied to clipboard
Incorrect db/schema.rb file for Postgres when using Cockroach and Postgres together.
In our Rails app we use both Postgres and Cockroach at the same time with Rails 6 multi-database support.
This adapter monkey patches ActiveRecord::ConnectionAdapters::PostgreSQL::Column#serial?
in a way that causes the Postgres db/schema.rb
file to be incorrectly generated, with primary key values like:
create_table "access_logs", id: :bigint, default: -> { "nextval('admin_access_logs_id_seq'::regclass)" }, force: :cascade do |t|
Instead of:
create_table "access_logs", force: :cascade do |t|
We've applied this patch below to fix the issue so that the @serial
value is still respected when it's been supplied for Postgres columns.
module ActiveRecord
# activerecord-cockroachdb-adapter monkey patches ActiveRecord::ConnectionAdapters::PostgreSQL::Column and
# overwrites the #serial? method in a way that works for Cockroach, but always returns false for Postgres.
#
# This affects the generation of db/schema.rb for Postgres because the primary key column is not identified.
#
# Replace the method with one that works for both Postgres and Cockroach.
#
# I'm not sure why activerecord-cockroachdb-adapter monkey patches the PostgreSQL::Column class instead of extending
# it, like it does for other classes.
module FixDbSchemaDump
# This combines two methods:
# - ActiveRecord::ConnectionAdapters::PostgreSQL::Column#serial?
# - ActiveRecord::ConnectionAdapters::CockroachDB::PostgreSQLColumnMonkeyPatch#serial?
#
# @serial will always be nil for Cockroach, but may be set for Postgres.
def serial?
@serial || default_function == "unique_rowid()"
end
end
ConnectionAdapters::PostgreSQL::Column.class_eval do
prepend FixDbSchemaDump
end
end
What's the reason for the CockroachDB adapter monkey patching the PostgresSQL::Column class instead of creating a subclass?