Ruby on rails 正在获取Rails中的最后一个相关记录

Ruby on rails 正在获取Rails中的最后一个相关记录,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,我一直在寻找最好的方法来做这个相当长的一段时间与平庸的结果,所以我决定在这里问 场景如下:我有三个模型,任务、用户和注释,基本上如下所示: class Task < ActiveRecord::Base belongs_to :user has_many :comments end class Comment < ActiveRecord::Base belongs_to :user belongs_to :task end class User < Act

我一直在寻找最好的方法来做这个相当长的一段时间与平庸的结果,所以我决定在这里问

场景如下:我有三个模型,任务、用户和注释,基本上如下所示:

class Task < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :task
end

class User < ActiveRecord::Base
  has_many :tasks
  has_many :comments
end
class Task < ActiveRecord::Base
  belongs_to :user
  has_many :comments
  has_one :last_comment, -> { order 'created_at' }, class_name: "Comment"
end
tasks = Task.joins(last_comment: :user)
  .includes(last_comment: :user)
  .order('tasks.created_at DESC').limit(10).load

它只生成一个查询,这正是我想要的!谢谢大家!

您可以尝试以下方法:

class Task
  scope :recent, order('created_at desc')
  scope :last, lambda{|n| limit: n }
end
现在您有了可重用的作用域:

Task.recent.last(10)
我猜您希望输出给定用户(比如当前登录用户)的最后10个任务


您可以尝试以下方法:

class Task
  scope :recent, order('created_at desc')
  scope :last, lambda{|n| limit: n }
end
现在您有了可重用的作用域:

Task.recent.last(10)
我猜您希望输出给定用户(比如当前登录用户)的最后10个任务


您必须加入表,并急切地加载数据以最小化查询数量

例如:

tasks=Task.joins(comments::user)
.includes(注释::用户)
.order('tasks.created_at DESC')
.极限(10).载荷
comments=tasks.first.comments#无查询,已加载
user=comments.first.user#无查询,已加载
这会将查询数量减少到一个(非常复杂),因此您必须确保您的索引符合要求!:-D

关于合并联接和包含的官方文档很模糊,但应该有助于:

编辑:

下面是一个演示应用程序,其模型与您的相同,使用上述方法执行即时加载。它使用两个查询来加载数据。启动应用程序以查看其运行情况


您必须加入表,并立即加载数据以最小化查询数量

例如:

tasks=Task.joins(comments::user)
.includes(注释::用户)
.order('tasks.created_at DESC')
.极限(10).载荷
comments=tasks.first.comments#无查询,已加载
user=comments.first.user#无查询,已加载
这会将查询数量减少到一个(非常复杂),因此您必须确保您的索引符合要求!:-D

关于合并联接和包含的官方文档很模糊,但应该有助于:

编辑:

下面是一个演示应用程序,其模型与您的相同,使用上述方法执行即时加载。它使用两个查询来加载数据。启动应用程序以查看其运行情况

您可以尝试以下方法:

class Task < ActiveRecord::Base
  belongs_to :user
  has_many :comments
  has_one :last_comment, :class_name => 'Comment', :order => 'comments.created_at DESC'
end

@tasks = Task.limit(10).includes(:last_comment => :user)
类任务comment',:order=>comments.created\u at DESC'
结束
@tasks=Task.limit(10).包括(:last_comment=>:user)
last_comment
是一个“虚拟”关联,只需加载一条
comment
记录。这种方法的优点是使用更少的内存(因为只需加载一条
注释
和一条相关的
用户
)。如果使用
includes(comments:user)
可能会消耗大量内存(如果有大量注释:)。

您可以尝试以下方法:

class Task < ActiveRecord::Base
  belongs_to :user
  has_many :comments
  has_one :last_comment, :class_name => 'Comment', :order => 'comments.created_at DESC'
end

@tasks = Task.limit(10).includes(:last_comment => :user)
类任务comment',:order=>comments.created\u at DESC'
结束
@tasks=Task.limit(10).包括(:last_comment=>:user)

last_comment
是一个“虚拟”关联,只需加载一条
comment
记录。这种方法的优点是使用更少的内存(因为只需加载一条
注释
和一条相关的
用户
)。如果使用
includes(comments:user)
可能会消耗大量内存(如果有大量注释:)。

这会产生:PG::Error:Error:missing FROM子句条目中的表“task”我已使用演示应用程序(SQLite3)更新了解决方案。试一试。也许我在某个地方错了,但当我尝试类似的方法时,我有一个左外部连接用于注释,它加载了所有注释,而不仅仅是10个,因此如果您有10个任务,并且每个任务都有10000条注释,您会遇到麻烦。这会产生:PG::Error:Error:缺少表“task”的子句条目我已经用一个演示应用程序(SQLite3)更新了解决方案。尝试一下。也许我在某个地方错了,但当我尝试类似的方法时,我有一个左外连接用于评论,它加载了所有的评论,而不仅仅是10条,所以如果你有10个任务,每个任务有10000条评论,你就有麻烦了。我认为我没有被正确理解,所以我用这个评论发表了进一步的解释:我关心的不是任务的限制,数量完全无关,我试图以某种方式模拟这样的场景,任务只有一条评论,所以问题是如何加载最后一条相关评论我认为我没有被正确理解,所以我用这条评论进一步解释:这不是我所关心的任务的限制,数字完全不相关,我试图以某种方式模拟场景,其中任务只有一条注释,因此问题是如何加载最后一条关联的注释。不要将
范围
与参数lambdas一起使用。改为使用类方法。因为这是使用类方法。如果我错了,请原谅我,但是Lukasz不是使用lamdas的首选方法,而是使用->形式而不是旧的lamba形式。不要使用带有参数的lambdas的
scope
。改为使用类方法。因为这是使用类方法。如果我错了,请原谅,但是Lukasz不是使用lamdas的首选方法,而是使用->形式而不是旧的lamba形式。未知键::顺序。有效键为::类名称,:匿名类,:外键,:验证,:自动保存,:外键类型,:依赖,:主键,:逆键,:必需,:as,:触摸(参数错误)未知键::顺序。有效键为::类名称、:匿名类、:外键、:验证、:自动保存