正如标题所说,我正在尝试访问关联的对象数组 这是一个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")
现在您可以访问position
、rating_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)