ruby on rails - ActiveRecord: How to find parents whose ALL children match a condition? -


suppose have parent model has many child, , child belongs otherparent.

how can find parent of child belongs otherparent?

in pure sql

parent.find_by_sql(<<sql)   select *   parents p   not exists (     select *     children     parent_id = p.id       , other_parent_id null   ) sql 

(from here), i'd prefer taking advantage of activerecord if possible.

thanks!


i'm using rails 4.2.1 , postgresql 9.3

using arel can pretty far. tricky part how not write entire query using arel's own query syntax?

here's trick: when building query using where, if use arel conditions, methods free. instance, can tail subquery have there .exists.not, (not ( exists (subquery))) toss parent's where-clause , you're set.

the question is, how reference tables involved? need arel that. could use arel's where ugly conditions a.eq b. why? since it's equality condition, can use rails' conditions instead! can reference table you're quering hash key, other table (in outer query) can use arel_table. watch this:

parents = parent.arel_table parent.where(   child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not ) 

you can reduce arel usage resorting strings little , relying on fact can feed in subqueries parameters rails' where. there not use it, doesn't force dig arel's methods much, can use trick or other sql operators take subquery (are there others?):

parents = parent.arel_table parent.where('not exists (?)',   child.where(parent_id: parents[:id], other_parent_id: nil) ) 

the 2 main points here are:

  • you can build subqueries same way used building regular queries, referencing outer query's table arel. may not real table, may alias! crazy stuff.
  • you can use subqueries parameters rails' where method fine.

Comments

Popular posts from this blog

Java 3D LWJGL collision -

spring - SubProtocolWebSocketHandler - No handlers -

methods - python can't use function in submodule -