Skip to content

Polymorphic search doesn't take polymorphic type into the query #1120

@Looooong

Description

@Looooong

Given the polymorphic example from the wiki:

Location.ransack(locatable_of_House_type_number_eq: 100).result

The final query doesn't compare locatable_type = 'House'. This would gives false result, as the House id can match IDs from other polymorphic types as well.

Here is the full specs:

# You can run this file directly using `ruby` command
# Given bundler and rspec 3 are installed globally
# It might be different if you are using rspec 2
require 'bundler/inline'
require 'rspec/autorun'
require 'rspec/core/formatters/progress_formatter'
require 'rspec/core/profiler'

# TODO: Define dependencies
gemfile true do
  source 'https://rubygems.org'
  gem 'sqlite3'
  gem 'rspec-expectations'

  gem 'activerecord', '~> 5.2', require: %w[active_record active_record/relation]
  gem 'activesupport', require: 'active_support/dependencies/autoload'
  gem 'ransack', github: 'activerecord-hackery/ransack', ref: '6434e3bedfbf4cc5d97d33c84d10682970a95083'
end

ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')

ActiveRecord::Schema.define do
  create_table :houses, force: true do |t|
  end

  create_table :locations, force: true do |t|
    t.references :locatable, polymorphic: true
  end
end

class House < ActiveRecord::Base
  has_one :location, as: :locatable
end

class Location < ActiveRecord::Base
  belongs_to :locatable, polymorphic: true
end

RSpec.describe Location, type: :model do
  it 'queries correctly' do
    expect(Location.ransack(locatable_of_House_type_id_eq: 123).result.to_sql).to eq(<<-SQL.squish)
      SELECT "locations".*
      FROM "locations"
      LEFT OUTER JOIN "houses" ON "houses"."id" = "locations"."locatable_id"
      WHERE "houses"."id" = 123
        AND "locations"."locatable_type" = 'House'
    SQL
end

Output:

Failures:

  1) Location queries correctly
     Failure/Error:
       expect(Location.ransack(locatable_of_House_type_id_eq: 123).result.to_sql).to eq(<<-SQL.squish)
         SELECT \"locations\".*
         FROM \"locations\"
         LEFT OUTER JOIN \"houses\" ON \"houses\".\"id\" = \"locations\".\"locatable_id\"
         WHERE \"houses\".\"id\" = 123
           AND \"locations\".\"locatable_type\" = 'House'
       SQL
     
       expected: "SELECT \"locations\".* FROM \"locations\" LEFT OUTER JOIN \"houses\" ON \"houses\".\"id\" = \"locati...ons\".\"locatable_id\" WHERE \"houses\".\"id\" = 123 AND \"locations\".\"locatable_type\" = 'House'"
            got: "SELECT \"locations\".* FROM \"locations\" LEFT OUTER JOIN \"houses\" ON \"houses\".\"id\" = \"locations\".\"locatable_id\" WHERE \"houses\".\"id\" = 123"
     
       (compared using ==)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions