我想使用包含关系的搜索条件,就像下面的
一样Post.includes(:tags).where( tags: { title: '%token%' }).all
posts
和tags
表已与名为post_tag_relations
的第3个表相关联。
架构如下所示:
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)
代替。
再次更新
看起来不能使用一个查询来获取,所以我已经尝试了另一个数据库模式......
答案 0 :(得分:0)
这样的事情:
Post.includes(:tags).where( "tags.title LIKE ?", "%#{token}%" )
可行。 (语法可能有点不对,抱歉,但你明白了)
答案 1 :(得分:0)
为什么不这样做:
Post.includes(:tags).where(Tag.arel_table[:title].matches('%token%').or(Tag.arel_table[:post_id].eq(nil)))
答案 2 :(得分:0)
自ruby-on-rails-2 joins
operation is used in all cases before the includes
operation during performance以来,但由于includes
使用LEFT OUTER JOIN
运算符,您应该使用它。您可能还需要使用LEFT
,但FULL
加入。所以尝试使用arel 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。