【问题标题】:Rails where not in array不在数组中的导轨
【发布时间】:2016-05-14 07:07:43
【问题描述】:

我有一些帖子,每个帖子都有很多标签。

我需要创建一个查询来匹配那些不具有数组中确切标签的帖子。

它还应该返回所有没有标签的帖子。

这是我尝试过的:

  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

这给了我所有没有标签的帖子,这是正确的,它也给了我没有指定标签的帖子,并且没有其他标签,这也是正确的.

问题是如果一个帖子有多个标签,比如test, another,它会在查询中返回它,这不是我想要的行为。

我需要过滤掉这些帖子,如果一个帖子有一个标签在数组中,是否包含另一个标签。

例子:

post1 has tag `test`
post2 has tag `another`
post3 has tags `test, another`
post4 has no tags

它应该返回:

[post2, post4]

但现在它返回了:

[post2, post3, post4]

【问题讨论】:

    标签: ruby ruby-on-rails-4 activerecord ruby-on-rails-3.2


    【解决方案1】:

    加入具有两个标签的post post_tags 会返回两行。

    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
    

    【讨论】:

      【解决方案2】:

      首先,您应该选择所有具有no_tags 的帖子,将其命名为excluded_posts。然后您进行查询以获取与excluded_posts 不同的所有帖子。这是 Rail 代码示例:

      excluded_post_ids = PostTag.where.not(name: no_tags).select(:post_id)
      expected_post = Post.where.not(id: excluded_post_ids)
      

      【讨论】:

      • 我认为这根本不是有效的,它会查询整个表。
      • 在第一次查询中,Rails 不会将所有对象加载到内存中,它只是生成查询字符串。是懒加载机制
      猜你喜欢
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 2015-04-16
      相关资源
      最近更新 更多