【问题标题】:How to use `matches()` with a database function?如何将`matches()`与数据库函数一起使用?
【发布时间】:2019-08-21 12:20:24
【问题描述】:

我有一个这样的 ActiveRecord 范围:

scope :matching, ->(query) {
  where Post.arel_table[:title].matches "%#{query}%"
}

这很好用。然后我将其更改为忽略title 中的额外空格:

scope :matching, ->(query) {
  where "regexp_replace(title, '\\s+', ' ', 'g') ILIKE ?", "%#{query}%"
}

这可行,但我不得不从 matches()(在 Ruby 级别)降到 ILIKE(在 SQL 级别)。

regexp_replace(...) 可以和matches() 一起使用吗?例如:

scope :matching, ->(query) {
  where handwaving("regexp_replace(title, '\\s+', ' ', 'g')").matches "%#{query}%"
}

(我尝试使用Arel::Nodes::NamedFunction,但无法使用。)

【问题讨论】:

    标签: arel


    【解决方案1】:

    是的,您可以按如下方式构造Arel::Nodes::NamedFunction

    condition = Arel::Nodes::NamedFunction.new(
       'regex_replace', 
       [Post.arel_attribute(:title),
        Arel.sql("'\\s+'"),
        Arel.sql("' '"), 
        Arel.sql("'g'")]
    ).matches("%#{query}%")
    

    然后

    scope :matching, ->(query) {
      # above condition code
      where(condition)
    }
    

    这将导致以下 (query = 'testing')

    SELECT 
      posts.*
    FROM 
      posts
    WHERE 
      regex_replace(posts.title, '\\s+',' ','g') ILIKE '%testing%'
    

    【讨论】:

    • 谢谢!我错过了 Arel.sql() 包装器并得到类型不匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 2019-06-05
    • 2019-05-29
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多