Ruby on rails 包含vs加入

Ruby on rails 包含vs加入,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有三种型号 用户-有许多借方和贷方 借方-属于用户 信用-属于用户 借方和贷方非常相似。这些字段基本相同。 我试图在我的模型上运行一个查询,以返回用户为当前用户的借方和贷方的所有字段 User.left_outer_joins(:debits, :credits).where("users.id = ?", @user.id) 正如预期的那样,用户返回所有字段的次数与贷方和借方记录的次数相同 User.includes(:credits, :debits).order(created_a

我有三种型号

  • 用户-有许多借方和贷方
  • 借方-属于用户
  • 信用-属于用户
借方和贷方非常相似。这些字段基本相同。 我试图在我的模型上运行一个查询,以返回用户为当前用户的借方和贷方的所有字段

User.left_outer_joins(:debits, :credits).where("users.id = ?", @user.id)
正如预期的那样,用户返回所有字段的次数与贷方和借方记录的次数相同

User.includes(:credits, :debits).order(created_at: :asc).where("users.id = ?", @user.id)
它运行了3个查询,我认为应该在一个查询中完成

问题的第二部分是。如何将记录类型添加到查询中

在信用记录中,会有一个额外的字段来显示信用和借记


我已经研究过ActiveRecordUnion gem,但我没有看到它如何解决这里的问题

包括
无法在一个查询中神奇地检索到您想要的所有内容;它将对您需要点击的每个模型(通常)运行一个查询。相反,它消除了不必要的查询。举以下例子:

坏的 这里总共有6个查询,一个对用户检索所有用户,然后一个对每个
。debitis
在循环中调用

好!! 在这里,您将只进行两个查询:一个是针对用户的查询,另一个是针对其关联的借项的查询。这就是
includes
通过急切地加载您知道需要的东西来加速应用程序的方式


至于您的评论,是的,将它们合并到一个表中似乎是有意义的。根据您的情况,我建议您研究单表继承(STI)。如果不这样做,请小心添加一个名为
type
的列,Rails不会喜欢这样

首先,在第一个查询中,通过调用User类上的查询,您要求的是User类型的记录,如果您不想要User对象,那么您将执行额外的连接,这可能会很昂贵。(可能不会,将来也会)

如果您想要信用和借记记录,只需调用对信用和借记模型的查询即可。如果在此点之前加载用户对象,请使用
包含
预加载
急切加载
一次性执行加载链接的贷记和借记记录

rails中有两种预加载记录的方式。在第一种情况下,rails对每种类型的记录执行一次查询,而第二种情况下,rails只执行一次查询,并使用返回的数据加载不同类型的对象。
includes
是一种智能预加载程序,它根据认为哪种方式更快来执行其中一种方式

如果您想强制rails在任何情况下都使用一个查询,
eager\u load
就是您想要的


请阅读文章中所有关于
的内容,包括
渴望加载
预加载
,实际上现在我已经想到了。如果信用卡和借记卡是同一个模型中的一个类型,那么这就更有意义了。我还看到,运行一个查询将无法工作,因为即使查询中的列相同,它们也需要指定为debit.colum1、debit.colum2、debit.colum3、credit.colum1、credit.colum2、credit.colum3
users = User.first(5)
users.each do |user|
  p user.debits.first
end
users = User.includes(:debits).first(5)
users.each do |user|
  p user.debits.first
end