2017-11-24 5 views
0

スコープ内に別の検索値を追加してterms.map に追加し、whereクエリに渡して、最小値と最大値を持たせたいのですが?値の範囲のレールを検索する

scope :search_query, lambda { |query| 
    return nil if query.blank? 

    # condition query, parse into individual keywords 
    terms = query.downcase.split(/\s+/) 

    # replace "*" with "%" for wildcard searches, 
    # append '%', remove duplicate '%'s 
    terms = terms.map { |e| 
    (e.gsub('*', '%') + '%').gsub(/%+/, '%') 
    } 
    num_or_conds = 2 
    where(
    terms.map { |term| 
     "(LOWER(students.first_name) LIKE ? OR LOWER(students.last_name) LIKE ?)" 
    }.join(' AND '), 
    *terms.map { |e| [e] * num_or_conds }.flatten 
) 
} 

私がやりたい何

.where(column_name BETWEEN #{value1} AND #{value2}) 

答えて

1

することはできだけのどこを繰り返し呼び出すことにより、レールでチェーンスコープ:あなたはまた、スコープをマージする.mergeを使用することができます

Thing.where(a: 1).where(b: 2) 
# SELECT things.* FROM things WHERE things.a = ? AND things.b = ? 

Thing.where(a: 1).merge(Thing.where(b: 2)) 

使用rangeクエリBETWEEN作成:

Thing.where(foo: (1..10)) 
# SELECT things.* FROM things WHERE foo BETWEEN 1 AND 10 

これはまた、日付と時刻のために動作します。

scopeには、クラスメソッドの構文糖だけがあります。したがって、メソッドが1行に収まらない場合は、「古典的」メソッド定義を使用する必要があります。

class Student < ApplicationRecord 
    def self.search_query(query) 
    scope = self.all 

    terms = query.downcase.split(/\s+/) 
    terms = terms.map { |e| 
     (e.gsub('*', '%') + '%').gsub(/%+/, '%') 
    } 

    self.all.tap do |scope| 
     terms.each do |term| 
     scope.merge(
      self.where("(LOWER(students.first_name) LIKE :t OR LOWER(students.last_name) LIKE :t)", t: term) 
     ) 
     end 
    end 
    end 
end 
+0

説明をいただきありがとうございます – John