ruby-on-rails
  • ruby-on-rails-4
  • activerecord
  • rails-activerecord
  • ruby-on-rails-5
  • 2015-06-28 10 views 64 likes 
    64

    Ich weiß, es gibt 3 Notationen für Argumente der where Active Methode liefert:Active OR Abfrage Hash Notation

    1. reine String
    2. Array
    3. Hash

    Angabe and für die where Methode ist geradlinig:

    # 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}) 
    

    Angabe von or für die gleiche where Methode stempelt mich für die Hash-Syntax. Ist es möglich?

    # 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}) 
    

    Antwort

    126

    Es gibt 5 Optionen, die als Implementierungen von «Hash-Notation» angesehen werden könnte (die letzten beiden sind irgendwie Hash ish):

    1. Mit Ruby on Rails 5 Sie in der Lage sind

      Person.where(name: 'Neil').or(Person.where(age: 27)) 
      
    2. Verwendung zusammen mit where_values: folgenden Verkettungs Verwendung ActiveRecord::Relation#or Methode zu tun. Die unscoped Methode ist notwendig only for Rails 4.1+ zu gewährleisten default_scope ist nicht in der where_values enthalten.Ansonsten Prädikate von beiden default_scope und where würde mit dem or Operator verkettet werden:

      Person.where( 
          Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) 
      ) 
      
    3. installieren Plugins von Drittanbietern, die diese oder ähnliche Merkmale, zum Beispiel implementieren:

      • Where Or(Rückportierung von Ruby on Rails 5 .or Feature oben erwähnt)

      • 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. Verwendung Arel:

      Person.where( 
          Person.arel_table[:name].eq('Neil').or(
          Person.arel_table[:age].eq(27) 
      ) 
      ) 
      
    5. Verwendung mit benannten Parametern Prepared Statements:

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

    Dies ist eine vollständige Antwort. Die 'arel' Antwort ist besonders gut, da dies, wie ich verstehe, zu Rails 5 hinzugefügt wird. –

    +0

    Wenn Sie nicht auf Rails 5 warten können, können Sie diesen Backport der Funktion zu Rails 4.2 verwenden. Gut verpackt als 'Where-or'-Juwel https://github.com/Eric-Guo/where-oder – Rob

    +0

    Wenn Ihr Projekt immer noch in Rails 3+ ist, können Sie versuchen, die Rails_oder Gem: https: // github. com/khiav223577/rails_or –

    1

    Wie sagt potashin Sie weitere Plugins von Drittanbietern verwenden, die diese Funktion implementieren . Ich habe eine lange Zeit mit Squeel und funktioniert ziemlich gut für diese und viele weitere Funktionen wie komplexe Unterabfragen oder Joins.

    Diese Abfrage mit squeel:

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