active-hash / active_hash

A readonly ActiveRecord-esque base class that lets you use a hash, a Yaml file or a custom file as the datasource
MIT License
1.2k stars 179 forks source link

ActiveRecordExtensions.belongs_to with extra arguments is not working #235

Open qsona opened 3 years ago

qsona commented 3 years ago

Environment

Problem

This works

class Bar < ApplicationRecord
  belongs_to :foo, primary_key: :code, foreign_key: :foo_code
end

But this doesn't work.

class Bar < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions

  belongs_to :foo, primary_key: :code, foreign_key: :foo_code
end

error message:

irb(main):004:0> Bar
/Users/qsona/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/activerecord-6.1.4/lib/active_record/associations/builder/association.rb:53:in `build_scope': undefined method `arity' for {:primary_key=>:code, :foreign_key=>:foo_code}:Hash (NoMethodError)

Note that this error occurs when the Bar class is first loaded, not when executing bar.foo .

Temporal solution

It can be avoided by first calling belongs_to and then extend ActiveHash::Associations::ActiveRecordExtensions.

e.g.

class Bar < ApplicationRecord
  belongs_to :foo, primary_key: :code, foreign_key: :foo_code

  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :baz
end

This solution cannot be used when you extend ApplicationRecord or ActiveRecord::Base directly ( ActiveRecord::Base.extend ActiveHash::Associations::ActiveRecordExtensions (docs).

Steps to Reproduce the Problem

# db/migrate/20210812100709_create_foos.rb
class CreateFoos < ActiveRecord::Migration[6.1]
  def change
    create_table :foos, id: false do |t|
      t.string :code, null: false, primary_key: true

      t.timestamps
    end
  end
end

# db/migrate/20210812100830_create_bars.rb
class CreateBars < ActiveRecord::Migration[6.1]
  def change
    create_table :bars do |t|
      t.string :foo_code, null: false

      t.timestamps
    end
  end
end
class Bar < ApplicationRecord
  # extend ActiveHash::Associations::ActiveRecordExtensions

  belongs_to :foo, primary_key: :code, foreign_key: :foo_code
end
Foo.create!(code: 'foo1')
bar = Bar.create!(foo_code: 'foo1')
bar.foo #=> #<Foo:0x00007f86840a1510 code: "foo1", created_at: Thu, 12 Aug 2021 10:11:01.476738000 UTC +00:00, updated_at: Thu, 12 Aug 2021 10:11:01.476738000 UTC +00:00>
class Bar < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions

  belongs_to :foo, primary_key: :code, foreign_key: :foo_code
end
Bar
/Users/qsona/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/activerecord-6.1.4/lib/active_record/associations/builder/association.rb:53:in `build_scope': undefined method `arity' for {:primary_key=>:code, :foreign_key=>:foo_code}:Hash (NoMethodError)
kbrock commented 3 years ago

I wonder if this is handled by https://github.com/zilkey/active_hash/pull/158 It is an old PR and stale by now - but is this addressing the same need?

issei-m commented 2 years ago

Any update?

aert commented 11 months ago

Having same issue here, rails 7.0.8, active_hash 2.3.0...

@qsona The temporary fix works, thanks!

@kbrock the needs seems not to be the same, basically I just added class_name: '...' to the belongs_to call and it is sufficient to raise the exception described.