khiav223577 / deep_pluck

Allow you to pluck attributes from nested associations without loading a bunch of records.
MIT License
460 stars 14 forks source link

HABTM STI parent and child referencing the same table #47

Closed TaylorMerritt closed 3 years ago

TaylorMerritt commented 3 years ago

Possibly related to https://github.com/khiav223577/deep_pluck/issues/46

deep_pluck uses the incorrect table name (uses the join table) for its query.

SQLite3::SQLException: no such column: training_programs_training_providers.training_program_id

begin
  require 'bundler/inline'
rescue LoadError => e
  warn 'Bundler version 1.10 or later is required. Please update your Bundler'
  raise e
end

gemfile(true) do
  source 'https://rubygems.org'
  gem 'deep_pluck', '~> 1.1.6'
  gem 'sqlite3'
end

require 'active_record'
require 'minitest/autorun'
require 'logger'

ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table 'training_programs', force: :cascade do |t|
    t.string :name
    t.integer :training_provider_id
  end

  create_table 'training_providers', force: :cascade do |t|
    t.string :name
    t.string :type
  end

  create_table 'training_programs_training_providers', id: false, force: :cascade do |t|
    t.bigint 'training_provider_id', null: false
    t.bigint 'training_program_id', null: false
  end
end

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

class TrainingProgram < ApplicationRecord
  belongs_to :training_provider
  has_and_belongs_to_many :borrower_apprenticeship_sponsors,
    class_name: 'ApprenticeshipSponsor',
    foreign_key: :training_program_id,
    association_foreign_key: :training_provider_id,
    inverse_of: :borrowed_training_programs,
    join_table: 'training_programs_training_providers'
end

class TrainingProvider < ApplicationRecord
  has_many :training_programs
end

class ApprenticeshipSponsor < TrainingProvider
  has_and_belongs_to_many :borrowed_training_programs,
    class_name: 'TrainingProgram',
    foreign_key: :training_provider_id,
    association_foreign_key: :training_program_id,
    inverse_of: :borrower_apprenticeship_sponsors,
    join_table: 'training_programs_training_providers'
end

class BugTest < Minitest::Test
  def setup
    TrainingProgram.create!(
      name: 'tp', borrower_apprenticeship_sponsors: [ApprenticeshipSponsor.create!(name: 'as')]
    )
  end

  def teardown
    ApprenticeshipSponsor.destroy_all
    TrainingProgram.destroy_all
  end

  def test_data
    assert_equal TrainingProgram.first.borrower_apprenticeship_sponsors.first.name, 'as'
  end

  def test_deep_pluck
    begin
      assert_equal TrainingProgram.deep_pluck(:name, borrower_apprenticeship_sponsors: :name), [
        'name' => 'tp',
        borrower_apprenticeship_sponsors: [
          'name' => 'as'
        ]
      ]
    rescue => e
      puts '-----'
      puts e
      puts '-----'
    end
  end
end
khiav223577 commented 3 years ago

Hi @taylor-au, thanks for the report. I tested and found it is related to https://github.com/khiav223577/deep_pluck/issues/46.