crashtech/torque-postgresql

Rails 7.1.1 incompatibilities

Closed this issue · 2 comments

On upgrading to Rails 7.1.1 from Rails 7.0 we encountered a couple of failures

We only use has_many :table_name, array: true and belongs_to_many features and these fixes allowed us to continue forward

Fix 1:

lib/torque/postgresql/inheritance.rb:60

def physically_inherited?
  return @physically_inherited if defined?(@physically_inherited)

  @physically_inherited = connection.schema_cache.dependencies(
    defined?(@table_name) ? @table_name : decorated_table_name,
  ).present?
rescue ActiveRecord::ConnectionNotEstablished
  false
end

This crashes on rails c when our Company model gets loaded with this error:

undefined method `dependencies' for #<ActiveRecord::ConnectionAdapters::BoundSchemaReflection

We don't use table inheritance so replacing the middle 3 lines with false fixed it

Fix 2:

lib/torque/postgresql/inheritance.rb:69

def inheritance_dependents
  connection.schema_cache.associations(table_name) || []
end

This fails with the below. We don't use inheritance features so commenting out the line and returning an empty array fixed this.

NoMethodError: undefined method `associations' for #<ActiveRecord::ConnectionAdapters::BoundSchemaReflection...

Fix 3:

lib/torque/postgresql/reflection/association_reflection.rb:20

def derive_foreign_key
  result = super
  result = ActiveSupport::Inflector.pluralize(result) \
    if collection? && connected_through_array?
  result
end

In rails 7.1 the kwarg was added infer_from_inverse_of with a boolean value defaulted to true. We fixed it by adding the same kwarg

See the super implementation:
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/reflection.rb:761

def derive_foreign_key(infer_from_inverse_of: true)
  if belongs_to?
    "#{name}_id"
  elsif options[:as]
    "#{options[:as]}_id"
  elsif options[:inverse_of] && infer_from_inverse_of
    inverse_of.foreign_key(infer_from_inverse_of: false)
  else
    active_record.model_name.to_s.foreign_key
  end
end

Caller:

/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/reflection.rb:507:in `foreign_key'"
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/associations/builder/belongs_to.rb:79:in `add_touch_callbacks'",
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/associations/builder/belongs_to.rb:23:in `define_callbacks'",
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/associations/builder/association.rb:34:in `build'",
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/associations.rb:1887:in `belongs_to'",
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activestorage-7.1.1/app/models/active_storage/attachment.rb:27:in `<class:Attachment>'",
/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activestorage-7.1.1/app/models/active_storage/attachment.rb:20:in `<main>'",

Fix 4:

lib/torque/postgresql/schema_cache.rb:215

def prepare_data_sources
  super
  @data_sources_model_names = Torque::PostgreSQL.config
    .irregular_models.slice(*@data_sources.keys).map do |table_name, model_name|
    [table_name, (model_name.is_a?(Class) ? model_name : model_name.constantize)]
  end.to_h
end

This method now take 1 arg which is a connection. See super implementation:

/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activerecord-7.1.1/lib/active_record/connection_adapters/schema_cache.rb:462

def prepare_data_sources(connection)
  tables_to_cache(connection).each do |source|
    @data_sources[source] = true
  end
end

Adding this 1 arg fixed it from crashing. We don't use connections to different dbs or schemas so this isn't affecting us

We won't be submitting a PR because we are damaging things

We're using
torque-postgresql (3.2.2)
rails (7.1.1)
ruby "3.2.2"

tomasc commented

@cameronmccord2 thanks, I just started a PR to address this – see #85.
Unfortunately the tests do not seem to run. Feel free to contribute if you find a minute.

@tomasc Your PR works within our project. Thanks!