【问题标题】:Select from one table with two foreign keys in a single query在单个查询中从具有两个外键的表中进行选择
【发布时间】:2015-06-20 16:46:51
【问题描述】:

我有两张桌子:

User:
user_id

user_blogs:
user_id | blog_id

blogs:
blog_id | source | identifier

Comments:
source | identifier | Field3

我希望能够选择用户拥有的博客中的所有 cmets。

我的模型是相关的:

class User < ActiveRecord::Base
  has_many :user_blogs
  has_many :blogs, trhough: :user_blogs
end

class blogs < ActiveRecord::Base
  has_many :comments, 
           :foreign_key => :source,
           :primary_key => :source,
           :conditions => Proc.new {
              {:identifier=> self.identifier}
           }
end

现在我可以使用以下方法检索所有用户 cmets:

User.first.blogs.map{|b| b.comments}

但这会为每个博客创建一个查询。

有没有办法一步完成?

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord arel


    【解决方案1】:
    class User < ActiveRecord::Base
      has_many :user_blogs
      has_many :blogs, through: :user_blogs
      has_many :comments, through: :blogs
    end
    
    class Blog < ActiveRecord::Base
      has_many :comments, -> { where(identifier: identifier) }, foreign_key : source, primary_key: source
    end
    
    
    User.find(ID).comments
    

    【讨论】:

      【解决方案2】:

      是的,您需要使用 Rails eager_loading 功能。

      u = User.includes(blogs: :comments)
      # now you can do
      u.first.blogs.map { |b| b.comments }
      

      或者,您也可以修改模型关联定义:

      class User < ActiveRecord::Base
        has_many :user_blogs
        has_many :blogs, -> { includes(:comments) }, through: :user_blogs
      end
      

      现在,您可以在不针对每个 blog 进行多个查询的情况下执行以下操作。

      User.first.blogs.map { |b| b.comments }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-24
        • 2015-02-12
        • 1970-01-01
        • 2012-08-15
        • 2014-10-17
        • 2017-09-12
        • 2017-08-02
        • 1970-01-01
        相关资源
        最近更新 更多