【问题标题】:What's the best way to include a LIKE clause in a Rails query?在 Rails 查询中包含 LIKE 子句的最佳方式是什么?
【发布时间】:2011-08-13 14:34:59
【问题描述】:

在 Rails 查询中包含 LIKE 子句的最佳方式是什么,例如(完全不正确):

 Question.where(:content => 'LIKE %farming%')

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord


    【解决方案1】:

    你会使用语法:

    Question.where("content LIKE ?" , "%#{farming}%")
    

    【讨论】:

    • 感谢您扩展问题,您将如何为该子句提供一系列条件。
    • 你可以这样做:Question.where("content LIKE ? AND name is like ?", "%#{search1}%", "%#{search2}%")
    • 谢谢你——当你写出来答案就很明显了!
    • 使用这个原始 SQL 只能在 SQLite 和 MySQL 上正常工作以进行不区分大小写的查询。使用 Postgres(例如在 Heroku 上)时,您需要使用 ILIKE 进行不区分大小写的查询,否则 LIKE 会区分大小写。
    • 这是不包括其他库的最佳答案。喜欢它。
    【解决方案2】:

    如果这是 Rails 3,您可以使用 Arel 的 matches。这具有与数据库无关的优点。例如:

    Question.where(Question.arel_table[:content].matches("%#{string}%"))
    

    这有点笨拙,但很容易提取到范围,例如:

    class Question
    
      def self.match_scope_condition(col, query)
        arel_table[col].matches("%#{query}%")
      end
    
      scope :matching, lambda {|*args|
        col, opts = args.shift, args.extract_options!
        op = opts[:operator] || :or
        where args.flatten.map {|query| match_scope_condition(col, query) }.inject(&op)
      }
    
      scope :matching_content, lambda {|*query|
        matching(:content, *query)
      }
    end
    
    Question.matching_content('farming', 'dancing') # farming or dancing
    Question.matching_content('farming', 'dancing', :operator => :and) # farming and dancing
    Question.matching(:other_column, 'farming', 'dancing') # same thing for a different col
    

    当然要加入“AND”,你可以链接范围。

    编辑:虽然 +1 到 metawhere 和 squeel(没有尝试过后者,但看起来很酷)它们都添加了这种类型的功能等等。

    【讨论】:

    • 非常酷,谢谢。我一直在阅读有关 Arel 的文章,但从未弄清楚它是什么
    • 你的瞄准镜丑得要命。使用类方法和比这更好的参数列表。
    • 您可以将此功能添加到所有 ActiveRecord::Base 后代,方法是将上述内容放在 config/initializers 目录中的文件中(为了便于阅读,我还编辑了名称): module ActiveRecord module Querying def match_scope_condition(column , query) arel_table[column].matches("%#{query}%") end def matching(*args) column_name, opts = args.shift, args.extract_options!运算符 = opts[:运算符] || :or where(args.flatten.map { |query| match_scope_condition(column_name, query) }.inject(&operator)) end end end
    【解决方案3】:

    如果你想要真正性感的条件并且没有外部依赖的问题,我强烈推荐MetaWhere 和它的继任者Squeel

    # MetaWhere
    Question.where(:content.like => '%farming%')
    
    # MetaWhere with operators overloaded
    Question.where(:content =~ '%farming%')
    
    # Squeel
    Question.where { :content.matches => '%farming%' }
    
    # Squeel with operators overloaded
    Question.where { :content =~ '%farming%' }
    

    【讨论】:

    • 对于 Squeel,正确的语法是 Question.where {content.matches '%farming%'}
    猜你喜欢
    • 2011-06-18
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多