Created
October 14, 2020 02:17
-
-
Save tjbarker/0e1d747c57f66f2838841e9090f7f5b8 to your computer and use it in GitHub Desktop.
Difference between checking presence of child association between active record relation and ransack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# code set up | |
class Big < ApplicationRecord | |
has_many :littles | |
end | |
class Little < ApplicationRecord | |
belongs_to :big # foreign_key is the default littles.big_id | |
end | |
# in console | |
Big.count # => 2 | |
Little.count # => 1 | |
# Using rails active relationship queries | |
## 1a) count of bigs that don't have a little | |
Big.left_outer_joins(:little).where(littles: { big_id: nil }).count | |
# => 1 | |
Big.left_outer_joins(:little).where(littles: { big_id: nil }).count.to_sql | |
# => SELECT bigs.* FROM bigs LEFT OUTER JOIN little ON littles.big_id = bigs.id WHERE littles.big_id IS NULL | |
## 1b) count of bigs that do have a little | |
Big.left_outer_joins(:little).where.not(littles: { big_id: nil }).count | |
# => 1 | |
Big.left_outer_joins(:little).where.not(littles: { big_id: nil }).to_sql | |
# => SELECT bigs.* FROM bigs LEFT OUTER JOIN little ON littles.big_id = bigs.id WHERE littles.big_id IS NOT NULL | |
# Using ransack present predicate | |
## 2a) count of bigs that don't have a little | |
Big.ransack(little_big_id_present: false).result.count | |
# => 1 | |
Big.ransack(little_big_id_present: false).result.sql | |
# => SELECT bigs.* FROM bigs LEFT OUTER JOIN littles ON littles.big_id = big.id WHERE (littles.big_id IS NULL OR littles.big_id != NULL) | |
# N.B this SQL evaluates to the same as 1a due to 'OR' in where clause. | |
## 2b) (attempting to query) count of bigs that have a little | |
Big.ransack(little_big_id_present: true).result.count | |
# => 0 | |
Big.ransack(little_big_id_present: true).result.to_sql | |
# => SELECT bigs.* FROM bigs LEFT OUTER JOIN littles ON littles.big_id = big.id WHERE (littles.big_id IS NOT NULL AND littles.big_id != NULL) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment