Ruby-on-rails ActiveRecord OR 查询哈希表示法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31096009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:16:29  来源:igfitidea点击:

ActiveRecord OR query Hash notation

ruby-on-railsruby-on-rails-4activerecordrails-activerecordruby-on-rails-5

提问by Neil

I know there are 3 main notations for supplying arguments to the whereActiveRecord method:

我知道为whereActiveRecord 方法提供参数有 3 个主要符号:

  1. Pure String
  2. Array
  3. Hash
  1. 纯弦
  2. 大批
  3. 哈希

Specifying andfor the wheremethod is straight forward:

指定andwhere方法是直截了当:

# Pure String notation
Person.where("name = 'Neil' AND age = 27")

# Array notation
Person.where(["name = ? AND age = ?", 'Neil', 27])

# Hash notation
Person.where({name: "Neil", age: 27})

Specifying orfor this same wheremethod is stumping me for the hash syntax. Is it possible?

指定or相同的where方法让我难以理解哈希语法。是否可以?

# Pure String notation
Person.where("name = 'Neil' OR age = 27")

# Array notation
Person.where(["name = ? OR age = ?", 'Neil', 27])

# Hash notation DOESN'T WORK
Person.where({name: "Neil" OR age: 27})

回答by potashin

There are 5 options that could be considered as implementations of ?Hash notation? (the last two are kinda hash-ish):

有 5 个选项可以被视为 ?Hash 符号的实现?(最后两个还挺散列ISH):

  1. With Ruby on Rails 5 you are able to do the following chaining using ActiveRecord::Relation#ormethod:

    Person.where(name: 'Neil').or(Person.where(age: 27))
    
  2. Use where_valuestogether with reduce. The unscopedmethod is necessary only for Rails 4.1+to ensure default_scopeis not included in the where_values. Otherwise predicates from both default_scopeand wherewould be chained with the oroperator:

    Person.where( 
      Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) 
    )
    
  3. Install third-party plugins that implement these or similar features, for example:

    • Where Or(backport of the Ruby on Rails 5 .orfeature mentioned above)

    • Squeel

      Person.where{(name == 'Neil') | (age == 27)} 
      
    • RailsOr

      Person.where(name: 'Neil').or(age: 27)
      
    • ActiverecordAnyOf

      Person.where.anyof(name: 'Neil', age: 27)
      
    • SmartTuple

      Person.where(
        (SmartTuple.new(' or ') << {name: 'Neil', age: 27}).compile
      )
      
  4. Use Arel:

    Person.where( 
      Person.arel_table[:name].eq('Neil').or(
        Person.arel_table[:age].eq(27)
      ) 
    )
    
  5. Use prepared statements with named parameters:

    Person.where('name = :name or age = :age', name: 'Neil', age: 27)
    
  1. 使用 Ruby on Rails 5,您可以使用ActiveRecord::Relation#or方法执行以下链接:

    Person.where(name: 'Neil').or(Person.where(age: 27))
    
  2. 使用where_values一起reduce。该unscoped方法仅对于 Rails 4.1+是必需的以确保default_scope不包含在where_values. 否则来自两者default_scope和的谓词where将与or运算符链接:

    Person.where( 
      Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) 
    )
    
  3. 安装实现这些或类似功能的第三方插件,例如:

    • Where Or (上述 Ruby on Rails 5.or功能的反向移植)

    • 尖叫声

      Person.where{(name == 'Neil') | (age == 27)} 
      
    • 铁轨或

      Person.where(name: 'Neil').or(age: 27)
      
    • ActiveRecordAnyOf

      Person.where.anyof(name: 'Neil', age: 27)
      
    • 智能元组

      Person.where(
        (SmartTuple.new(' or ') << {name: 'Neil', age: 27}).compile
      )
      
  4. 使用阿雷尔

    Person.where( 
      Person.arel_table[:name].eq('Neil').or(
        Person.arel_table[:age].eq(27)
      ) 
    )
    
  5. 使用带有命名参数的准备好的语句:

    Person.where('name = :name or age = :age', name: 'Neil', age: 27)
    

回答by Antonio Grass

As says potashin, you can use another third-party plugins that implement this feature. I have a long time using Squeeland works pretty well for this and much more features like complex subqueries or joins.

正如potashin所说,您可以使用另一个实现此功能的第三方插件。我有很长时间使用Squeel并且在这方面工作得很好,还有更多的功能,比如复杂的子查询或连接。

That query using squeel:

使用 squeel 的查询:

@people= Person.where{(name == 'Neil') | (age = 27)}