从深度嵌套模型中获取最近的记录



假设我有3个模型:

ModelA有许多ModelB模型b有许多模型c

我正在查询ModelA,但在ModelC中我有多个相同类型的,假设我有3个,但我只需要最近的一个。

我试着做这样的事情…

records = ModelA.where(some query).includes ModelB includes ModelC
// convert activerecord collection to array
records = records.to_a
records.each do |record|
record.modelBs.each do |modelB|
filter the modelCs i don't need
modelB.modelCs = filteredModelCs
end
end
return records

,但不只是返回记录数组,而是运行UPDATE sql查询并修改db记录。这是一个惊喜,因为我从未使用过。save方法,我认为我已经将集合从活动记录集合转换为数组

如何在不修改数据库记录的情况下过滤深度嵌套的记录?然后我可以返回过滤后的结果

将实例列表分配给具有=has_many集合,将立即将更改持久化到数据库中。

相反,我会尝试用更具体的关联来解决这个问题,像这样:
class A
has_many :bs
has_many(:cs, through: :bs)
has_one :recent_c, -> { order(created_at: :desc).limit(1) }, source: :cs
class B
has_many :cs

对于这些关联,我希望下面的操作能够工作:

as = A.where(some query).includes(:recent_c)
as.each do |a|
a.recent_c # returns the most recent c for this a
end

如果我没猜错的话,你想要得到一个最新的c的集合,这些c与b相连,而b与某个a关系相连?如果是这样,您可以这样做(考虑到您有表asbscs):

class A < ApplicationRecord
has_many :bs
end
class B < ApplicationRecord
belongs_to :a
has_many :cs
end
class C < ApplicationRecord
belongs_to :b
scope :recent_for_bs, -> { joins(
<<-sql
INNER JOIN (SELECT b_id, MAX(id) AS max_id FROM cs GROUP BY b_id) recent_cs
ON cs.b_id = recent_cs.b_id AND cs.id = recent_cs.max_id
sql
) }
end

然后你会像这样查询c:

C.recent_for_bs.joins(b: :a).merge(A.where(some_query))

你得到最近的c,将它们与b和a内部连接,然后通过合并得到与a关系相连的记录。

最新更新