Rails ActiveRecord Access 关联(子级?)最新创建的对象



正如标题所说,我正在尝试访问关联的对象数组 这是一个has_many协会

这是我的班级

class Keyword < ApplicationRecord
has_many :rankings
end

class Ranking < ApplicationRercord
belongs_to :keyword
end

排名中有一个名为 position:integer 的属性,我希望能够从所有关键字访问所有最新创建的排名,这就是我到目前为止得到的

Keyword.all.joins(:rankings).select( 'MAX(rankings.id) ').pluck(:created_at, :keyword_id, :position)

我已经阅读了其他一些建议我在 rankings.id 上使用MAX的文章,但我仍然无法返回数组

目前关键字计数返回 4597 排名.计数返回 9245

每个关键字都产生了大约 2 个排名,但我只想要每个关键字的最新排名数组格式,所以要获得每个关键字的最新排名,我应该期望在 4597 左右

不知道我解释得不够清楚,希望你们能帮助我:'(谢谢真的很感激

如果您使用的是Postgres。您可以使用DISTINCT ON

Keyword.joins(:rankings)
.select("DISTINCT ON(ratings.keyword_id) keywords.*, ratings.position, ratings.created_at AS rating_created_at")
.order("ratings.keyword_id, ratings.id DESC") 

现在您可以访问positionrating_created_at

@keywords.each do |k|
k.position
....
@keywords.map { |k| [k.id, k.rating_created_at, k.position] }

如果你有足够的排名,你可能希望在关键词表上存储最新的排名作为读取优化:

class Keyword < ApplicationRecord
belongs_to :latest_ranking, class_name: :ranking
has_many :rankings, after_add: :set_latest_ranking
def set_latest_ranking(ranking)
self.update!(latest_ranking: ranking)
end
end
Keyword.joins(:latest_ranking)
.pluck(:created_at, :id, "rankings.position")

这使得它既非常容易加入又具有高性能。在处理了一个行数很大的应用程序并尝试了所有可能的解决方案(如横向联接(以提高查询的相当糟糕的性能后,我学到了这一点。

成本是创建记录时的额外写入查询。

Keyword.joins(:rankings).group("keywords.id").pluck("keywords.id", "MAX(rankings.id)")

这将为您提供一个数组,该数组的元素将包括与该keyword相关联的keyword的 ID 和最新ranking的 ID。

如果您需要获取有关rankings而不是id的更多信息,您可以这样做:

last_rankings_ids_scope = Ranking.joins(:keyword).group("keywords.id").select("MAX(rankings.id)")
Ranking.where(id: last_rankings_ids_scope).pluck(:created_at, :keyword_id, :position)

最新更新