【问题标题】:Join tables - Associations in Rails 3连接表 - Rails 3 中的关联
【发布时间】:2012-02-05 08:41:21
【问题描述】:

例如,我有 2 个表:topics 和 cmets。

主题 has_many cmets。评论belongs_to topic。

评论表有列 sender_id 我保存创建此评论的用户 ID。

任务:选择主题的id,这个用户没有评论(我知道user_id)。 (我想用一个查询来完成)。

之前我就是这样做的。 (两个查询)(我的数据库 - PostgreSQL)

incorrect_topics = Comment.select(:topic_id).where(:sender_id => user_id).map { |elem| elem.topic_id }
ids = select(:id).where(["id NOT IN (?)", incorrect_topics]).map { |elem| elem.id }

它工作正常,但我想如果应用程序变得更大,那将是一个严重的问题。

谢谢。

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-3 postgresql associations


    【解决方案1】:

    如果您只需要 ID,那么您可以绕过所有 ActiveRecord 内容并手动完成:

    ids = connection.select_rows(%Q{
        select id
        from topics
        where id not in (
            select topic_id
            from comments
            where sender_id = #{user_id.to_i}
        )
    }).map { |r| r.first.to_i }
    

    如果您确定user_id 已经是一个整数,那么您不需要.to_i。你也可以使用#{connection.quote(user_id)}。如果您想避免使用 map 手动解开行,您也可以使用与 select_values 相同的 SQL。

    如果您想要 Topic 实例,那么find_by_sql 将是一个选项:

    topics = find_by_sql(%q{
        select *
        from topics
        where id not in (
            select topic_id
            from comments
            where sender_id = :user_id
        )
    }, :user_id => user_id)
    

    使用直接 SQL 比尝试将其包装在 ActiveRecord 中时更清楚。

    【讨论】:

    • 我没有尝试,但它必须工作。但是我可以不通过查询中的查询来做到这一点吗?但只有一个查询?不能在这里加入帮助我吗? JOIN 可以更快吗?
    • @rusak1:查询优化器会知道如何处理这样一个简单的查询,而且它的优势是非常清晰。
    • 最后一个问题:您对 JOIN 有什么看法?快吗?数据库难吗?
    • 使用 select_values 不是更好吗? apidock.com/rails/ActiveRecord/ConnectionAdapters/…
    • 联接很棒,数据库也很擅长。是的,这将是使用select_values 的好地方。
    【解决方案2】:

    也许这样的事情可以工作:

    incorrect_topics = Comment.where('sender_id <> ?', user_id).topics
    

    如果对你有帮助,请告诉我。

    【讨论】:

    • 考虑对主题 3 发表评论的用户 1 和 2,Comment.where('sender_id &lt;&gt; ?', user_id).topics 将把主题 3 交给您,即使用户 2 对它发表了评论。
    • Kleber S.,感谢您提供的变体,但它不正确。 mu太短是对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多