Rails où condition utilisant NOT NULL

En utilisant le style rails 3, comment pourrais-je écrire le contraire de:

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

Je veux trouver où id n’est pas nul. J’ai essayé:

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

Mais cela revient:

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

Ce n’est certainement pas ce dont j’ai besoin et ressemble presque à un bug dans ARel.

    La manière canonique de faire cela avec Rails 3:

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

    ActiveRecord 4.0 et supérieur ajoute where.not vous pouvez faire ceci:

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

    Lorsque je travaille avec des étendues entre des tables, je préfère tirer parti de la merge pour pouvoir utiliser plus facilement les étendues existantes.

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

    De plus, depuis que includes ne choisit pas toujours une stratégie de jointure, vous devez également utiliser des references ici, sinon vous risquez de vous retrouver avec un code SQL non valide.

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

    Je ne recommande plus d’utiliser Squeel pour cela car il ne dispose pas toujours d’un responsable à temps plein, et cela dépend des API privées qui provoquent des changements fréquents.

    Ce n’est pas un bug dans ARel, c’est un bogue dans votre logique.

    Ce que vous voulez ici est:

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

    Pour Rails4:

    Donc, ce que vous voulez, c’est une jointure interne, vous devez donc utiliser le prédicat de jointure:

      Foo.joins(:bar) Select * from Foo Inner Join Bars ... 

    Mais pour l’enregistrement, si vous voulez une condition “NOT NULL”, utilisez simplement le prédicat not:

     Foo.includes(:bar).where.not(bars: {id: nil}) Select * from Foo Left Outer Join Bars on .. WHERE bars.id IS NOT NULL 

    Notez que cette syntaxe signale une dépréciation (il s’agit d’un extrait de chaîne SQL, mais je suppose que la condition de hachage est remplacée par une chaîne dans l’parsingur?), Veillez donc à append les références à la fin:

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

    AVERTISSEMENT DE DEPRECATION: Il semble que vous soyez impatient (e) de charger des tables (une parmi: ….) qui sont référencées dans un extrait de chaîne SQL. Par exemple:

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

    Actuellement, Active Record reconnaît la table dans la chaîne et sait joindre la table de commentaires à la requête, plutôt que de charger des commentaires dans une requête distincte. Cependant, cela sans écrire un parsingur SQL complet est insortingnsèquement vicié. Comme nous ne voulons pas écrire un parsingur SQL, nous supprimons cette fonctionnalité. A partir de maintenant, vous devez indiquer explicitement à Active Record lorsque vous référencez une table à partir d’une chaîne:

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

    Avec Rails 4, c’est facile:

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

    Voir aussi: http://guides.rubyonrails.org/active_record_querying.html#not-conditions

    Je ne suis pas sûr de cela, mais ce qui a fonctionné pour moi dans Rails 4

     Foo.where.not(bar: nil)