Is there a way to invert an ActiveRecord::Relation query?

前端 未结 4 720
太阳男子
太阳男子 2021-02-08 03:31

Let\'s say we have the following:

irb> Post.where(:hidden => true).to_sql
=> \"SELECT `posts`.* FROM `posts` WHERE posts.hidden = 1\"

相关标签:
4条回答
  • 2021-02-08 04:04

    We can take Zabba's answer further by passing the inverted query back into ActiveRecord:

    table = Post.arel_table
    query = table[:hidden].eq(true).not # the inverted query, still ARel
    Post.where(query) # plug it back into ActiveRecord
    

    This will return ActiveRecord objects, as you would normally expect.

    0 讨论(0)
  • 2021-02-08 04:22

    What I do when I'm looking for records with a "not true" condition (eg, false or nil) is:

    Post.where(["(hidden IS NULL) OR (hidden = ?)", false])
    
    0 讨论(0)
  • 2021-02-08 04:24

    With a different syntax, yes. Example:

    posts = Post.scoped.table # or Arel::Table.new("posts")
    posts.where(posts[:hidden].eq(true).not).to_sql
    # => SELECT  FROM `posts` WHERE NOT ((`posts`.`hidden` = 1))
    
    0 讨论(0)
  • 2021-02-08 04:25

    In rails 4 there is not suffix for this purpose:

    Post.where.not(hidden: true).to_sql
    # => SELECT FROM `posts` WHERE `posts`.`hidden` != 1
    

    In rails 3 you can use squeel gem. It gives many usefull features. And with it you can write:

    Post.where{ hidden != true }.to_sql
    # => SELECT FROM `posts` WHERE `posts`.`hidden` != 1
    
    0 讨论(0)
提交回复
热议问题