【问题标题】:how to use LIKE in included relations如何在包含关系中使用 LIKE
【发布时间】:2014-11-28 18:01:17
【问题描述】:

我想使用包含关系的搜索条件,如下所示

Post.includes(:tags).where( tags: { title: '%token%' }).all

poststags 表已与名为 post_tag_relations 的第三个表关联。
架构如下:

posts
 id: pk
 title: string
 content: text

tags
 id: pk
 title: string

post_tag_relations
 id: pk
 tag_id: integer
 post_id: integer

语法只适用于相等条件,我真的不知道如何使用LIKE搜索条件。

当使用Post.joins(:tags)Tag.area_table[:title].matches('%token%') 时,它可以正常工作,但是一些没有标签的帖子将不会被提取。

谁能帮帮我?非常感谢。


更新:

Rails 版本是 4.1。

我想搜索posts.title LIKE '%token%' OR tags.title LIKE '%token%' 之类的帖子,所以如果使用Post.joins(:tags),如果某些帖子没有标签,将无法正常工作。所以我需要改用Post.includes(:tags)


再次更新:

看起来不能使用单查询来获取,所以我已经尝试了另一个数据库架构...

【问题讨论】:

  • 那么您希望实现哪个最终条件?标签匹配的帖子,没有标签的帖子?
  • @МалъСкрылевъ 感谢您的回复,我已经更新了详细信息。
  • 你能显示你的表的架构吗?您的表格标签和帖子是否都有“标题”列
  • @AaditiJain 是的,poststags 表都有 title 列。
  • 不太明白,如果你尝试匹配标签的标题,你需要没有标签的帖子吗?

标签: ruby-on-rails arel


【解决方案1】:

为什么不这样做:

Post.includes(:tags).where(Tag.arel_table[:title].matches('%token%').or(Tag.arel_table[:post_id].eq(nil)))

【讨论】:

  • @Francis.TM 在tags 表中有一个名为title 的列吗?
【解决方案2】:

由于joins operation is used in all cases before the includes operation during performance,但由于includes 使用LEFT OUTER JOIN 运算符,你应该使用它。可能您还需要使用不是LEFT,而是FULL 加入。所以用 gem试试这个:

class Post
   scope :with_token(token), -> do |token|
      re = Regexp.union(token).to_s
      cond = Arel.sql("title REGEXP ? OR content REGEXP ?", re, re)
      includes(:tags).where(Tag.arel_table[:title].eq(token).or(cond))
   end
end

当然可以替换原来的条件使用LIKE操作符:

class Post
   scope :with_token(token), -> do |token|
      includes(:tags).where(arel_table[:title].matches("%#{token}%")
         .or(arel_table[:content].matches("%#{token}%")
         .or(Tag.arel_table[:title].eq(token))))
   end
end

注意:如果有错误,请提供结果SQL。

【讨论】:

    【解决方案3】:

    类似这样的:

    Post.includes(:tags).where( "tags.title LIKE ?", "%#{token}%" )
    

    可以工作。 (语法可能有点错误,对不起,但你明白了)

    【讨论】:

      猜你喜欢
      • 2020-01-30
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 2015-04-22
      • 2015-11-06
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      相关资源
      最近更新 更多