ransack
ransack copied to clipboard
Custom Ransacker defaults to type = integer when combined with another integer search
I have a custom ransacker:
ransacker :exact_merchandise_item_ids, type: :string do |parent|
query = "(SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id)"
Arel.sql(query)
end
It works fine by itself:
Order.ransack(exact_merchandise_item_ids_matches: "123,124").result.to_sql
=> "SELECT `orders`.* FROM `orders` WHERE ((SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id) LIKE '123,124')"
But when combined with another search (of any type), it's cast as an integer, for some reason:
Order.ransack(exact_merchandise_item_ids_matches: "123,124", customer_id_eq: 1).result.to_sql
=> "SELECT `orders`.* FROM `orders` LEFT OUTER JOIN `customers` ON `customers`.`id` = `orders`.`customer_id` WHERE (((SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id) LIKE 123 AND `customers`.`id` = 1))"
More strangely yet, some other types, like datetime do work. If set type: :datetime, I get:
SELECT `orders`.* FROM `orders` LEFT OUTER JOIN `customers` ON `customers`.`id` = `orders`.`customer_id` WHERE (((SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id) LIKE '2018-04-19 04:01:23' AND `customers`.`id` = 1))
I'm happy to be told what I'm doing wrong, if anything. Otherwise, if someone can point me to the place in the code to fix this, I'm happy to submit a PR.
It's also worth mentioning that the order here matters:
44] pry(main)> Location.ransack(item_id_string_eq: 'AA').result.to_sql
=> "SELECT `locations`.* FROM `locations` WHERE CONVERT(locations.item_id, CHAR(8)) = 'AA'"
[45] pry(main)> Location.ransack(warehouse_id_eq: 1, item_id_string_eq: 'AA').result.to_sql
=> "SELECT `locations`.* FROM `locations` WHERE ((`locations`.`warehouse_id` = 1 AND CONVERT(locations.item_id, CHAR(8)) = 0))"
[46] pry(main)> Location.ransack(item_id_string_eq: 'AA', warehouse_id: 1).result.to_sql
=> "SELECT `locations`.* FROM `locations` WHERE CONVERT(locations.item_id, CHAR(8)) = 'AA'"
[47] pry(main)> Location.ransack(item_id_string_eq: 'AA', warehouse_id_eq: 1).result.to_sql
=> "SELECT `locations`.* FROM `locations` WHERE ((CONVERT(locations.item_id, CHAR(8)) = 'AA' AND `locations`.`warehouse_id` = 1))"
When the ransacker comes first, it works fine.
Last strange thing--it's only with with integer columns:
8] pry(main)> Location.ransack(name_eq: 'AA', item_id_string_eq: 'AA').result.to_sql
=> "SELECT `locations`.* FROM `locations` WHERE ((`locations`.`name` = 'AA' AND CONVERT(locations.item_id, CHAR(8)) = 'AA'))"
[49] pry(main)> Location.ransack(item_id_eq: 'AA', item_id_string_eq: 'AA').result.to_sql
=> "SELECT `locations`.* FROM `locations` WHERE ((`locations`.`item_id` = 0 AND CONVERT(locations.item_id, CHAR(8)) = 0))"
I have a custom ransacker:
ransacker :exact_merchandise_item_ids, type: :string do |parent| query = "(SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id)" Arel.sql(query) endIt works fine by itself:
Order.ransack(exact_merchandise_item_ids_matches: "123,124").result.to_sql => "SELECT `orders`.* FROM `orders` WHERE ((SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id) LIKE '123,124')"But when combined with another search (of any type), it's cast as an integer, for some reason:
Order.ransack(exact_merchandise_item_ids_matches: "123,124", customer_id_eq: 1).result.to_sql => "SELECT `orders`.* FROM `orders` LEFT OUTER JOIN `customers` ON `customers`.`id` = `orders`.`customer_id` WHERE (((SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id) LIKE 123 AND `customers`.`id` = 1))"More strangely yet, some other types, like
datetimedo work. If settype: :datetime, I get:SELECT `orders`.* FROM `orders` LEFT OUTER JOIN `customers` ON `customers`.`id` = `orders`.`customer_id` WHERE (((SELECT GROUP_CONCAT(DISTINCT order_items.item_id ORDER BY order_items.item_id ASC) FROM order_items WHERE order_items.order_id = orders.id) LIKE '2018-04-19 04:01:23' AND `customers`.`id` = 1))I'm happy to be told what I'm doing wrong, if anything. Otherwise, if someone can point me to the place in the code to fix this, I'm happy to submit a PR.
let me create a pull request on this issue