Pregunta

El uso de los carriles de 3 estilo de cómo iba a escribir lo contrario de:

Foo.includes(:bar).where(:bars=>{:id=>nil})

Quiero encontrar donde id no es nula. Probé:

Foo.includes(:bar).where(:bars=>{:id=>!nil}).to_sql

Pero que los rendimientos:

=> "SELECT     \"foos\".* FROM       \"foos\"  WHERE  (\"bars\".\"id\" = 1)"

Esto definitivamente no es lo que necesito, y casi parece un error en Arel.

¿Fue útil?

Solución

La forma canónica de hacer esto con Rails 3:

Foo.includes(:bar).where("bars.id IS NOT NULL")

ActiveRecord 4.0 y superior añade where.not para que pueda hacer esto:

Foo.includes(:bar).where.not('bars.id' => nil)
Foo.includes(:bar).where.not(bars: { id: nil })

Cuando se trabaja con alcances entre tablas, prefiero apalancamiento merge de modo que pueda utilizar ámbitos existentes con mayor facilidad.

Foo.includes(:bar).merge(Bar.where.not(id: nil))

Además, dado que includes no siempre elige una estrategia de combinación, se debe utilizar references aquí también , de lo contrario puede terminar con SQL válido.

Foo.includes(:bar)
   .references(:bar)
   .merge(Bar.where.not(id: nil))

Otros consejos

No es un error en Arel, que es un error en la lógica.

Lo que se quiere aquí es:

Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))

Para Rails4:

Por lo tanto, lo que está queriendo es una combinación interna, lo que realmente debe utilizar sólo las uniones de predicados:

  Foo.joins(:bar)

  Select * from Foo Inner Join Bars ...

Sin embargo, para el registro, si quieres un "NO NULO" afección simplemente no utilizar el predicado:

Foo.includes(:bar).where.not(bars: {id: nil})

Select * from Foo Left Outer Join Bars on .. WHERE bars.id IS NOT NULL

Tenga en cuenta que esta sintaxis reporta una depreciación (se habla de un fragmento de cadena SQL, pero supongo que la condición de hash se cambia a cadena en el analizador?), Así que asegúrese de agregar las referencias al final:

Foo.includes(:bar).where.not(bars: {id: nil}).references(:bar)
  

Deprecation ADVERTENCIA: Parece que usted está ansioso mesa de carga (s) (uno   de: ....) que se hace referencia en un fragmento de cadena SQL. Por ejemplo:

Post.includes(:comments).where("comments.title = 'foo'")
     

Actualmente, Active Record reconoce la mesa en la cadena, y sabe   Para unirse a la mesa de comentarios a la consulta, en lugar de cargar los comentarios   en una consulta separada. Sin embargo, hacer esto sin tener que escribir un lleno-soplado   intérprete de SQL está viciado. Dado que no queremos escribir una consulta SQL   analizador, vamos a eliminar esta funcionalidad. A partir de ahora, debe   decirle explícitamente Registro Activo cuando se hace referencia a una tabla de una   cadena:

Post.includes(:comments).where("comments.title = 'foo'").references(:comments)

No estoy seguro de que esto sea útil, pero esto lo que funcionó para mí en los carriles 4

Foo.where.not(bar: nil)

Con los carriles 4 es fácil:

 Foo.includes(:bar).where.not(bars: {id: nil})

Consulte también:      http://guides.rubyonrails.org/active_record_querying.html#not-conditions

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top