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 broke ActiveRecord sql when same table and different "belongs_to" joining (even though not use ransack search) #1253

Closed
kei-p opened this issue Sep 28, 2021 · 1 comment

Comments

@kei-p
Copy link

kei-p commented Sep 28, 2021

I just updated the ransack gem from 2.3.2 to 2.4.2 and found a puzzling bug.
This bug is lost "JOIN" query partially when same table and different "belongs_to" joining query even though not use ransack search method.
I found this bug caused by ransack 2.4.2 ( maybe 2.4.x) by below example code and results.

Results

rails ransack test
6-1-stable v2.4.2 Failed
6-0-stable v2.4.2 Failed
6-1-stable master(4caf7c2) Failed
6-0-stable v2.3.2 Pass
6-1-stable no use (comment out "ransack") Pass

Example code

unless File.exist?('Gemfile')
  File.write('Gemfile', <<-GEMFILE)
    source 'https://rubygems.org'

    # Rails master
    gem 'rails', github: 'rails/rails', branch: '6-1-stable'

    gem 'pg'
    gem 'ransack', github: 'activerecord-hackery/ransack', tag: 'v2.4.2'
  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.
`psql -c "DROP DATABASE IF EXISTS ransack_bug_report;"`
`psql -c "CREATE DATABASE ransack_bug_report;"`
ActiveRecord::Base.establish_connection(adapter: 'postgresql', database: 'ransack_bug_report')
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 :tasks, force: true do |t|
    t.bigint :user_id
    t.bigint :reviewer_id
  end

  create_table :users, force: true do |t|
  end
end

class Task < ActiveRecord::Base
  belongs_to :user
  belongs_to :reviewer, class_name: 'User', optional: true
end

class User < ActiveRecord::Base
  has_many :tasks
end

class BugTest < Minitest::Test
  def test_active_record_join
    user = User.create!
    Task.create!(user: user, reviewer: nil)

    sql = Task.joins(:user).left_outer_joins(:reviewer).to_sql
    assert_match /INNER JOIN "users"/, sql
    assert_match /LEFT OUTER JOIN "users" "reviewers_tasks"/, sql
  end
end

Result detail ( case: "rails=6-1-stable, ransack=2.4.2" )

Fetching https://github.com/rails/rails.git
Fetching https://github.com/activerecord-hackery/ransack.git
Fetching gem metadata from https://rubygems.org/.......
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/............
Resolving dependencies....
Using rake 13.0.6
Using concurrent-ruby 1.1.9
Using i18n 1.8.10
Using minitest 5.14.4
Using tzinfo 2.0.4
Using zeitwerk 2.4.2
Using activesupport 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using builder 3.2.4
Using erubi 1.10.0
Using mini_portile2 2.6.1
Using racc 1.5.2
Using nokogiri 1.12.5 (x86_64-darwin)
Using rails-dom-testing 2.0.3
Using crass 1.0.6
Using loofah 2.12.0
Using rails-html-sanitizer 1.4.2
Using actionview 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using rack 2.2.3
Using rack-test 1.1.0
Using actionpack 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using nio4r 2.5.8
Using websocket-extensions 0.1.5
Using websocket-driver 0.7.5
Using actioncable 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using globalid 0.5.2
Using activejob 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using activemodel 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using activerecord 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using marcel 1.0.2
Using mini_mime 1.1.1
Using activestorage 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using mail 2.7.1
Using actionmailbox 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using actionmailer 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using actiontext 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using bundler 2.1.4
Using method_source 1.0.0
Using pg 1.2.3
Using thor 1.1.0
Using railties 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using sprockets 4.0.2
Using sprockets-rails 3.2.2
Using rails 6.1.4.1 from https://github.com/rails/rails.git (at 6-1-stable@3be6c2d)
Using ransack 2.4.1 from https://github.com/activerecord-hackery/ransack.git (at v2.4.2@7fc3166)
Bundle complete! 3 Gemfile dependencies, 44 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
====================================================================================
Running test case with Ruby 2.7.4, Active Record 6.1.4.1, Arel 10.0.0 and PostgreSQL
====================================================================================
-- create_table(:tasks, {:force=>true})
D, [2021-09-28T10:07:48.797272 #76360] DEBUG -- :    (0.3ms)  DROP TABLE IF EXISTS "tasks"
D, [2021-09-28T10:07:48.804603 #76360] DEBUG -- :    (6.8ms)  CREATE TABLE "tasks" ("id" bigserial primary key, "user_id" bigint, "reviewer_id" bigint)
   -> 0.0082s
-- create_table(:users, {:force=>true})
D, [2021-09-28T10:07:48.805365 #76360] DEBUG -- :    (0.4ms)  DROP TABLE IF EXISTS "users"
D, [2021-09-28T10:07:48.809412 #76360] DEBUG -- :    (3.9ms)  CREATE TABLE "users" ("id" bigserial primary key)
   -> 0.0047s
D, [2021-09-28T10:07:48.892205 #76360] DEBUG -- :    (3.2ms)  CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL)
D, [2021-09-28T10:07:48.912285 #76360] DEBUG -- :   ActiveRecord::InternalMetadata Load (0.4ms)  SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", "environment"], ["LIMIT", 1]]
D, [2021-09-28T10:07:48.924445 #76360] DEBUG -- :   TRANSACTION (0.5ms)  BEGIN
D, [2021-09-28T10:07:48.927013 #76360] DEBUG -- :   ActiveRecord::InternalMetadata Create (1.6ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key"  [["key", "environment"], ["value", "default_env"], ["created_at", "2021-09-28 01:07:48.923201"], ["updated_at", "2021-09-28 01:07:48.923201"]]
D, [2021-09-28T10:07:48.928197 #76360] DEBUG -- :   TRANSACTION (0.6ms)  COMMIT
Run options: --seed 23250

# Running:

D, [2021-09-28T10:07:49.034579 #76360] DEBUG -- :   TRANSACTION (0.1ms)  BEGIN
D, [2021-09-28T10:07:49.036076 #76360] DEBUG -- :   User Create (1.1ms)  INSERT INTO "users" DEFAULT VALUES RETURNING "id"
D, [2021-09-28T10:07:49.039997 #76360] DEBUG -- :   TRANSACTION (3.5ms)  COMMIT
D, [2021-09-28T10:07:49.052031 #76360] DEBUG -- :   TRANSACTION (0.1ms)  BEGIN
D, [2021-09-28T10:07:49.053070 #76360] DEBUG -- :   Task Create (0.7ms)  INSERT INTO "tasks" ("user_id") VALUES ($1) RETURNING "id"  [["user_id", 1]]
D, [2021-09-28T10:07:49.053777 #76360] DEBUG -- :   TRANSACTION (0.4ms)  COMMIT
F

Failure:
BugTest#test_active_record_join [bug_report_templates/test-ransack-join-queries.rb:64]:
Expected /LEFT OUTER JOIN "users" "reviewers_tasks"/ to match "SELECT \"tasks\".* FROM \"tasks\" INNER JOIN \"users\" ON \"users\".\"id\" = \"tasks\".\"user_id\"".


rails test bug_report_templates/test-ransack-join-queries.rb:58



Finished in 0.036198s, 27.6258 runs/s, 110.5033 assertions/s.
1 runs, 4 assertions, 1 failures, 0 errors, 0 skips

@deivid-rodriguez
Copy link
Contributor

deivid-rodriguez commented Oct 23, 2023

I'm going to close this since #1447 is likely to have fixed this. Feel free to reopen if not though!

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

2 participants