Rails 不在数组中
Rails where not in array
我有一些 post,每个都有很多标签。
我需要创建一个与 post 匹配的查询,这些 post 没有与数组中的标签完全相同。
此外,它还应该 return 所有 post 完全没有标签的查询。
这是我尝试过的:
query = posts.joins('LEFT JOIN post_tags ON post.id = post_tags.post_id')
no_tags = ['test', 'test1']
query = query.where('post_tags.name NOT IN (?) OR post_tags.name IS ?', no_tags, nil) if no_tags
这给了我所有没有标签的 post,这是正确的,它还给了我没有指定标签的 post,并且没有其他标签,这也是正确的。
问题是,如果 post 有 多个 标签,比如 test, another
,它 return 在查询中包含它,这这不是我想要的行为。
我需要过滤掉这些post,如果post有一个标签在数组中,是否包含其他标签。
示例:
post1 has tag `test`
post2 has tag `another`
post3 has tags `test, another`
post4 has no tags
应该return:
[post2, post4]
但现在 returns:
[post2, post3, post4]
首先,你应该 select 所有有 no_tags
的帖子,称之为 excluded_posts
。然后您进行查询以获取与 excluded_posts
不同的所有帖子。这是铁路代码示例:
excluded_post_ids = PostTag.where.not(name: no_tags).select(:post_id)
expected_post = Post.where.not(id: excluded_post_ids)
加入一个 post
有两个标签 post_tags
returns 两行。
post_name post_tag
test3 test
test3 another
您现在应该明白为什么 'test3' 包含在您的结果中了。对每一行结果进行检查,其中之一作为有效结果通过。
考虑做类似的事情
no_tags = ['test', 'test1']
query = query.where('post.id NOT IN (SELECT post_id FROM post_tags WHERE name IN (?))',
no_tags) if no_tags
我有一些 post,每个都有很多标签。
我需要创建一个与 post 匹配的查询,这些 post 没有与数组中的标签完全相同。
此外,它还应该 return 所有 post 完全没有标签的查询。
这是我尝试过的:
query = posts.joins('LEFT JOIN post_tags ON post.id = post_tags.post_id')
no_tags = ['test', 'test1']
query = query.where('post_tags.name NOT IN (?) OR post_tags.name IS ?', no_tags, nil) if no_tags
这给了我所有没有标签的 post,这是正确的,它还给了我没有指定标签的 post,并且没有其他标签,这也是正确的。
问题是,如果 post 有 多个 标签,比如 test, another
,它 return 在查询中包含它,这这不是我想要的行为。
我需要过滤掉这些post,如果post有一个标签在数组中,是否包含其他标签。
示例:
post1 has tag `test`
post2 has tag `another`
post3 has tags `test, another`
post4 has no tags
应该return:
[post2, post4]
但现在 returns:
[post2, post3, post4]
首先,你应该 select 所有有 no_tags
的帖子,称之为 excluded_posts
。然后您进行查询以获取与 excluded_posts
不同的所有帖子。这是铁路代码示例:
excluded_post_ids = PostTag.where.not(name: no_tags).select(:post_id)
expected_post = Post.where.not(id: excluded_post_ids)
加入一个 post
有两个标签 post_tags
returns 两行。
post_name post_tag
test3 test
test3 another
您现在应该明白为什么 'test3' 包含在您的结果中了。对每一行结果进行检查,其中之一作为有效结果通过。
考虑做类似的事情
no_tags = ['test', 'test1']
query = query.where('post.id NOT IN (SELECT post_id FROM post_tags WHERE name IN (?))',
no_tags) if no_tags