64

Tôi biết có 3 ký hiệu chính để cung cấp đối số cho phương pháp where ActiveRecord Hash truy vấn:ActiveRecord HOẶC ký hiệu

  1. tinh khiết Chuỗi
  2. Mảng
  3. Hash

Xác định and cho Phương pháp where là thẳng về phía trước:

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

Chỉ định or cho phương thức này giống như where đang cho tôi biết cú pháp băm. Có thể không?

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

Trả lời

126

Có 5 tùy chọn có thể được coi là hiện thực của «ký hiệu Hash» (người cuối cùng hai là kinda hash- ish):

  1. Với Ruby on Rails 5 bạn có thể để làm chaining sau sử dụng ActiveRecord::Relation#or phương pháp:

    Person.where(name: 'Neil').or(Person.where(age: 27)) 
    
  2. sử dụng where_values cùng với reduce. Phương pháp unscoped là cần thiết only for Rails 4.1+ để đảm bảo default_scope không được bao gồm trong where_values.Nếu không predicates từ cả hai default_scopewhere sẽ bị xiềng xích với or điều hành:

    Person.where( 
        Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) 
    ) 
    
  3. Cài đặt plugin của bên thứ ba thực hiện các hoặc tương tự tính năng, ví dụ:

    • Where Or(backport của Ruby on Rails 5 .or tính năng được đề cập ở trên)

    • 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. Sử dụng Arel:

    Person.where( 
        Person.arel_table[:name].eq('Neil').or(
        Person.arel_table[:age].eq(27) 
    ) 
    ) 
    
  5. Sử dụng chuẩn bị báo cáo với tên thông số:

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

Đây là một câu trả lời hoàn chỉnh. Câu trả lời 'arel' đặc biệt tốt vì đây là những gì được thêm vào Rails 5, như tôi đã hiểu. –

+0

Nếu bạn không thể đợi Rails 5, bạn có thể sử dụng cổng sau của đối tượng địa lý này để tạo đường ray 4.2. Được đóng gói độc đáo như viên đá quý “hoặc” https://github.com/Eric-Guo/where-or – Rob

+0

Nếu dự án của bạn vẫn còn trong Rails 3+, bạn có thể thử đá quý rails_or: https: // github. com/khiav223577/rails_or –

1

Như nói potashin, bạn có thể sử dụng một plugin của bên thứ ba mà thực hiện tính năng này . Tôi có một thời gian dài sử dụng Squeel và hoạt động khá tốt cho điều này và nhiều tính năng khác như truy vấn con phức tạp hoặc tham gia.

Đó truy vấn sử dụng squeel:

@people= Person.where{(name == 'Neil') | (age = 27)} 
Các vấn đề liên quan