Subscription
has_many
:versions
模型
我正在编写一个查询,以获取订阅并按照关联的versions
最后一个authorized_at
日期对它们进行排序,但由于joins
和group
语句,我不确定查询能否多次返回相同的订阅。
Subscription
.joins(:versions)
.group("subscriptions.id, users.id")
.order("MAX(versions.authorized_at) ASC")
另一方面,我有一个Subscription
实例方法current_version
,它返回最后一个授权的version
。
subscription.rb
def current_version
versions.authorized.last
end
我认为关联(而不是实例方法)可以帮助我,因此我可以加入订阅表和版本表,并按照关联的表授权日期对结果进行排序。
但是,如何像类方法那样编写执行查询的关联呢?
,我试过做了如下的事情:
has_one :current_version,
-> { versions.authorized.last },
class_name: "Version", inverse_of: "Subscription"
但我得到了NameError: undefined local variable or method 'versions' for #<Version::ActiveRecord_Relation
发布于 2021-09-23 09:47:27
读取性能的最佳解决方案是将一个单独的外键列作为捷径添加到表中:
add_reference :subscriptions,
:current_version,
foreign_key: {
to_table: :versions
}
class Subscription < ApplicationRecord
has_many :versions,
after_add: :set_current_version
belongs_to :current_version,
class_name: 'Version'
def set_current_version(version)
update_attribute(:current_version_id, version.id)
end
end
这将使用一组位置回调来设置关联,但也可以使用DB触发器或服务对象来处理它。
如果你真的想使用has_one
,你需要像子查询一样使用黑客,窗口函数或后置连接
class Subscription
has_one :current_version,
-> {
where(
id: Version.select(:id)
.group(:subscription_id)
.order("MAX(versions.authorized_at) ASC")
)
},
class_name: 'Version'
end
发布于 2021-09-24 03:42:13
我通过max尝试了上面的答案,它在控制台中工作(我只尝试了has_one
的提议),但是我无法使视图正常工作(我一直得到未定义的表错误)。
最后,我创建了一个使用它的current_version
(上一次授权version
)获取订阅的范围,并使用了该范围。
scope :with_current_version, -> {
select("subscriptions.*, last_version.authorized_at AS last_version_authorized_at")
.joins("LEFT OUTER JOIN (SELECT DISTINCT ON (subscription_id) * FROM versions
ORDER BY versions.subscription_id,
versions.authorized_at DESC) AS last_version
ON last_version.subscription_id = subscriptions.id")
}
然后在我的控制器里:
@subscriptions = current_account.subscriptions.with_current_version
.order("last_version_authorized_at ASC")
https://stackoverflow.com/questions/69302391
复制相似问题