ransack icon indicating copy to clipboard operation
ransack copied to clipboard

Ransack is not correctly overriding/using previous joins

Open omitter opened this issue 7 years ago • 2 comments

Joining fails when using multiple search patterns at once, when joining a table that ransack wants to join later for searching.

Having these aliases in the Order model (Order belongs to Collection and Customer (User) through CustomerRelation)

ransack_alias :uname, :customer_relation_customer_name
ransack_alias :cname, :collection_name

Running the following ransack generated queries, sql fails:

Order.joins(:collection).ransack({:uname_cont=>"foo", :cname_cont=>"bar"}).result.page(1).to_a
#=> ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'collections_orders.name' in 'where clause':
 SELECT  `orders`.* 
FROM `orders` 
INNER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id`
 LEFT OUTER JOIN `customer_relations` ON `customer_relations`.`id` = `orders`.`customer_relation_id`
 LEFT OUTER JOIN `customers` ON `customers`.`id` = `customer_relations`.`customer_id` 
WHERE (`customers`.`name` LIKE '%foo%' AND `collections_orders`.`name` LIKE '%bar%')
 LIMIT 25 OFFSET 0
# from /usr/local/rvm/gems/ruby-2.4.0/gems/mysql2-0.4.8/lib/mysql2/client.rb:120:in `_query'

Order.left_outer_joins(:collection).ransack({:uname_cont=>"foo",cname_cont=>"bar"}).result.page(1).to_a
#=> ActiveRecord::StatementInvalid: Mysql2::Error: Not unique table/alias: 'collections': 
SELECT  `orders`.* 
FROM `orders`
 LEFT OUTER JOIN `customer_relations` ON `customer_relations`.`id` = `orders`.`customer_relation_id`
 LEFT OUTER JOIN `customers` ON `customers`.`id` = `customer_relations`.`customer_id`
 LEFT OUTER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id` 
LEFT OUTER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id` 
WHERE (`customers`.`name` LIKE '%foo%' AND `collections`.`name` LIKE '%bar%') 
LIMIT 25 OFFSET 0

Order.left_outer_joins(:collection).ransack({cname_cont: 'bar'}).result.page(1).to_a
#=> ActiveRecord::StatementInvalid: Mysql2::Error: Not unique table/alias: 'collections': 
SELECT  `orders`.* FROM `orders` 
LEFT OUTER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id`
 LEFT OUTER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id`
 WHERE (`collections`.`name` LIKE '%bar%') 
LIMIT 25 OFFSET 0
# from /usr/local/rvm/gems/ruby-2.4.0/gems/mysql2-0.4.8/lib/mysql2/client.rb:120:in `_query'

but this does miraculously work (as it should)

Order.joins(:collection).ransack({cname_cont: 'bar'}).result.page(1).to_a
  Order Load (0.9ms)  SELECT  `orders`.* FROM `orders` INNER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id` WHERE (`collections`.`name` LIKE '%bar%') LIMIT 25 OFFSET 0

as does this (changing the hash order of the initial example⁉)

Order.joins(:collection).ransack({cname_cont: 'bar', uname_cont: 'foo'}).result.page(1).to_a
  Order Load (1.4ms)  SELECT  `orders`.* FROM `orders` INNER JOIN `collections` ON `collections`.`id` = `orders`.`collection_id` LEFT OUTER JOIN `customer_relations` ON `customer_relations`.`id` = `orders`.`customer_relation_id` LEFT OUTER JOIN `customers` ON `customers`.`id` = `customer_relations`.`customer_id` WHERE (`collections`.`name` LIKE '%bar%' AND `customers`.`name` LIKE '%foo%') LIMIT 25 OFFSET 0

So left_outer_joins does never work and joins works depending on the hash order ransack receives… confusing.

omitter avatar Aug 04 '17 06:08 omitter

Got the same error, I believe it related to this issue. https://github.com/activerecord-hackery/ransack/issues/374

Alias doesn't properly apply.

wuboy0307 avatar Aug 18 '17 07:08 wuboy0307

I got the same error, the hash order ransack receives differs the result!

zephyrpathsofglory avatar Feb 13 '19 07:02 zephyrpathsofglory