如何只使用一次数据库调用多次调用作用域

时间:2015-02-05 12:55:23

标签: sql ruby-on-rails ruby ruby-on-rails-4 named-scope

我有一个Product的数据库,并且我想要搜索产品name属性。我使用范围来做到这一点:

scope name_contains, lambda{|q| where("name LIKE ?", "%#{q}%")}

当我搜索“Awesome Product”并且该产品被称为“一个非常棒的产品”时工作正常,但是当我搜索“产品很棒”时却没有,因为这些字的方向错误。我接下来尝试的是按空格分割查询并调用每个单词的范围:

def self.search(q)
  q.split(" ").map(&:strip).select{|x| !x.empty? }.each_with_index do |word,index|
    if index == 0
      data = Product.name_contains(word)
    else
      data = data.name_contains(word)
    end
  end
  data
end

哪个有效,但每个单词都会触及数据库。但我知道rails可以更好地处理这个问题,因为:

Product.name_contains("awesome").name_contains("product")

只打一次数据库。这是我想要的,但在迭代中调用name_contains方法时无法实现。

1 个答案:

答案 0 :(得分:1)

类似

words.inject(Product.all) {|scope, word| scope.name_contains(word)}

应该做的伎俩。在rails 4之前,您需要Product.scoped而不是Product.all

请注意,这将需要全表扫描(除非您有其他条件将要应用) - mysql将无法使用此查询的任何索引