Rieles donde la condición usa NOT NIL
Usando el estilo Rails 3, ¿cómo escribiría lo opuesto a:
Foo.includes(:bar).where(:bars=>{:id=>nil})
Quiero encontrar dónde la identificación NO es nula. Lo intenté:
Foo.includes(:bar).where(:bars=>{:id=>!nil}).to_sql
Pero eso regresa:
=> "SELECT \"foos\".* FROM \"foos\" WHERE (\"bars\".\"id\" = 1)"
Definitivamente eso no es lo que necesito y casi parece un error en ARel.
Aceptado
Rieles 4+
ActiveRecord 4.0 y superiores agregan where.not
para que puedas hacer esto:
Foo.includes(:bar).where.not('bars.id' => nil)
Foo.includes(:bar).where.not(bars: { id: nil })
Cuando trabajo con ámbitos entre tablas, prefiero aprovecharlos merge
para poder utilizar los ámbitos existentes más fácilmente.
Foo.includes(:bar).merge(Bar.where.not(id: nil))
Además, dado que includes
no siempre elige una estrategia de unión, references
también debe utilizarla aquí; de lo contrario, puede terminar con un SQL no válido.
Foo.includes(:bar)
.references(:bar)
.merge(Bar.where.not(id: nil))
Rieles 3
La forma canónica de hacer esto con Rails 3:
Foo.includes(:bar).where("bars.id IS NOT NULL")
No es un error en ARel, es un error en tu lógica.
Lo que quieres aquí es:
Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))