Skip to content

Instantly share code, notes, and snippets.

@linkyndy
Created April 14, 2015 12:33
Show Gist options
  • Save linkyndy/e84534e1cdc19dd8e4cc to your computer and use it in GitHub Desktop.
Save linkyndy/e84534e1cdc19dd8e4cc to your computer and use it in GitHub Desktop.
Working example of searching self-joined, nested models with ransack. With Rails >4.0 join is made on the wrong association while on Rails 4.0 it works as expected
class CreateClients < ActiveRecord::Migration
def change
create_table :clients do |t|
t.string :type
t.references :party, index: true
t.references :master_client, index: true
t.timestamps
end
end
end
class CreateParties < ActiveRecord::Migration
def change
create_table :parties do |t|
t.string :name
t.timestamps
end
end
end

Steps to reproduce the issue:

  1. Clone this Gist in two environments, one running Rails 4.0, one running Rails 4.1/4.2.

  2. Run bundle install and rake db:migrate (don't forget to change the Rails version in the Gemfile);

  3. Open the rails console:

rails c
  1. Create some test data. Here's an example:
p1 = Party.create(name: 'Party 1')
p2 = Party.create(name: 'Party 2')
mc = MasterClient.create(party: p1)
c = Client.create(party: p2, master_client: mc)
  1. Issue a ransack search:
Client.ransack('master_client_party_name_cont' => 'arty').result
  1. Observe the generated query:

a. On Rails 4.0, the query looks as expected:

SELECT "clients".* 
FROM "clients" 
  LEFT OUTER JOIN "clients" "master_clients_clients" ON "master_clients_clients"."id" = "clients"."master_client_id" AND "master_clients_clients"."type" IN ('MasterClient') 
  LEFT OUTER JOIN "parties" ON "parties"."id" = "master_clients_clients"."party_id" 
WHERE ("parties"."name" LIKE '%arty%')

b. On Rails 4.1/4.2, the last join is built the wrong way:

SELECT "clients".* 
FROM "clients" 
  LEFT OUTER JOIN "clients" "master_clients_clients" ON "master_clients_clients"."id" = "clients"."master_client_id" AND "master_clients_clients"."type" IN ('MasterClient') 
  LEFT OUTER JOIN "parties" ON "parties"."id" = "clients"."party_id" 
WHERE ("parties"."name" LIKE '%arty%')
class Client < ActiveRecord::Base
belongs_to :party
belongs_to :master_client
end
gem 'rails', '4.0.0' # Then change this to '4.2.0'
gem 'ransack'
class MasterClient < Client
end
class Party < ActiveRecord::Base
has_one :client
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment