Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ransack throws an error when doing a query that joins twice to the same table. #1182

Closed
sebaas opened this issue Dec 2, 2020 · 4 comments
Closed

Comments

@sebaas
Copy link

sebaas commented Dec 2, 2020

require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'

  gem 'rails', '6.0.3.4'
  gem 'pg'
  gem 'pry'
  gem 'ransack', '2.4.0', require: false
end

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

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

ActiveRecord::Schema.define do
  create_table :arms, force: true do |t|
    t.string :name
    t.integer :amount_of_finger
  end

  create_table :robots, force: true do |t|
    t.string :name
    t.references :left_arm, index: true, foreign_key: { to_table: :arms }
    t.references :right_arm, index: true, foreign_key: { to_table: :arms }
  end
end

class Robot < ActiveRecord::Base
  belongs_to :right_arm, dependent: :destroy, class_name: 'Arm'
  belongs_to :left_arm, dependent: :destroy, class_name: 'Arm'
end

class Arm < ActiveRecord::Base
  has_one :robot
end

class RansackFindsTheObject < ActiveSupport::TestCase
  def setup
    @left_arm = Arm.create!(name: 'left', amount_of_finger: 6)
    @right_arm = Arm.create!(name: 'right', amount_of_finger: 3)
    @robot = Robot.create!(name: 'Wall-e', left_arm: @left_arm, right_arm: @right_arm)
    @q = {'right_arm_name_eq' => 'right', 'left_arm_name_eq' => 'left'}
  end


  def test_ransack_filtering_works
    assert_includes Robot.ransack(@q).result, @robot
  end
end

This proves the error with Rails version 6.0.3 and Ransack version 2.4.0
This throws an error:

Error:
RansackFindsTheObject#test_ransack_filtering_works:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "left_arms_robots"
LINE 1: ..."right_arm_id" WHERE ("arms"."name" = 'right' AND "left_arms...

It was also evaluated for an older version of rails (5.2.4) with Ransack version 2.4.0
And this works:

require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'

  gem 'rails', '5.2.4'
  gem 'pg'
  gem 'pry'
  gem 'ransack', '2.4.0', require: false
end

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

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

ActiveRecord::Schema.define do
  create_table :arms, force: true do |t|
    t.string :name
    t.integer :amount_of_finger
  end

  create_table :robots, force: true do |t|
    t.string :name
    t.references :left_arm, index: true, foreign_key: { to_table: :arms }
    t.references :right_arm, index: true, foreign_key: { to_table: :arms }
  end
end

class Robot < ActiveRecord::Base
  belongs_to :right_arm, dependent: :destroy, class_name: 'Arm'
  belongs_to :left_arm, dependent: :destroy, class_name: 'Arm'
end

class Arm < ActiveRecord::Base
  has_one :robot
end

class RansackFindsTheObject < ActiveSupport::TestCase
  def setup
    @left_arm = Arm.create!(name: 'left', amount_of_finger: 6)
    @right_arm = Arm.create!(name: 'right', amount_of_finger: 3)
    @robot = Robot.create!(name: 'Wall-e', left_arm: @left_arm, right_arm: @right_arm)
    @q = {'right_arm_name_eq' => 'right', 'left_arm_name_eq' => 'left'}
  end


  def test_ransack_filtering_works
    assert_includes Robot.ransack(@q).result, @robot
  end
end

Also works for rails 6.1.0.rc2 with Ransack 2.4.0

But for Rails version 6.0.3 and Ransack version 2.3.2 It continues failing

This is related to issue #1151 and #1144

@prsanjay
Copy link

I have faced the same issue with Rails 6.0.2 and Ransack 2.4.0

After upgrading Rails version to 6.1.0 it all works well!

@yahonda
Copy link
Contributor

yahonda commented Dec 30, 2020

According to git bisect, this issue has been addressed at Rails 6-0-stable branch via rails/rails@f9ba524 .

If Rails 6.0.4 is released this fix should be included.

@kaspernj
Copy link
Contributor

An updated test works for me with Postgres:

unless File.exist?('Gemfile')
  File.write('Gemfile', <<-GEMFILE)
    source 'https://rubygems.org'
    # Rails master
    gem 'rails', github: 'rails/rails', branch: '6-1-stable'
    # Rails last release
    # gem 'rails'
    gem 'sqlite3'
    gem 'ransack', github: 'activerecord-hackery/ransack'
  GEMFILE

  system 'bundle install'
end

require 'bundler'
Bundler.setup(:default)

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

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(
  adapter: 'postgresql',
  database: 'ransack_test',
  host: 'postgres',
  user: 'username',
  password: 'password'
)
ActiveRecord::Base.logger = Logger.new(STDOUT)

# Display versions.
message = "Running test case with Ruby #{RUBY_VERSION}, Active Record #{
  ::ActiveRecord::VERSION::STRING}, Arel #{Arel::VERSION} and #{
  ::ActiveRecord::Base.connection.adapter_name}"
line = '=' * message.length
puts line, message, line

ActiveRecord::Schema.define do
  create_table :arms, force: true do |t|
    t.string :name
    t.integer :amount_of_finger
  end

  create_table :robots, force: true do |t|
    t.string :name
    t.references :left_arm, index: true #, foreign_key: { to_table: :arms }
    t.references :right_arm, index: true #, foreign_key: { to_table: :arms }
  end
end

class Robot < ActiveRecord::Base
  belongs_to :right_arm, dependent: :destroy, class_name: 'Arm'
  belongs_to :left_arm, dependent: :destroy, class_name: 'Arm'
end

class Arm < ActiveRecord::Base
  has_one :robot
end

class RansackFindsTheObject < ActiveSupport::TestCase
  def setup
    @left_arm = Arm.create!(name: 'left', amount_of_finger: 6)
    @right_arm = Arm.create!(name: 'right', amount_of_finger: 3)
    @robot = Robot.create!(name: 'Wall-e', left_arm: @left_arm, right_arm: @right_arm)
    @q = {'right_arm_name_eq' => 'right', 'left_arm_name_eq' => 'left'}
  end

  def test_ransack_filtering_works
    assert_includes Robot.ransack(@q).result, @robot
  end
end

@deivid-rodriguez
Copy link
Contributor

I'll close since this was addressed in Rails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants