ruby-on-rails - 如何将实例方法转换为关联?
问题描述
型号Subscription
has_many
:versions
。
我正在编写一个查询来获取订阅并按关联的versions
最后日期对其进行排序,但是由于and语句authorized_at
,我不确定该查询是否可以多次返回相同的订阅。joins
group
Subscription
.joins(:versions)
.group("subscriptions.id, users.id")
.order("MAX(versions.authorized_at) ASC")
另一方面,我有返回最后一个授权的Subscription
实例方法。current_version
version
订阅.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
解决方案
读取性能的最佳解决方案是在表中添加单独的外键列作为捷径:
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
这使用关联回调来设置关联,但您也可以使用数据库触发器或服务对象来处理它。
如果你真的想使用has_one
,你需要使用hackery,比如子查询、窗口函数或横向连接:
class Subscription
has_one :current_version,
-> {
where(
id: Version.select(:id)
.group(:subscription_id)
.order("MAX(versions.authorized_at) ASC")
)
},
class_name: 'Version'
end
推荐阅读
- drake - 如何使用 MeshCat 和 pydake 将 drake 的可视化输出通过管道传输到端口?
- python-3.x - 在日期时间序列中查找事件的平均年龄
- c# - 序列化名称值对列表,不包括键和值部分
- java - 如何在多对多关系 [Spring Boot 2、JPA、Hibernate、PostgreSQL] 中的一个操作中保存多个实体
- scala - 从 csv 创建数据框并使用 inferSchema 转换列比创建数据框和使用 withColumn 转换要慢得多
- r - 使用传单包查找点之间的最短路径并在地图上绘图
- kubernetes - 始终将 pod 与 pvc 和 gce 永久磁盘搭配使用
- javascript - 如何在国家地图中添加悬停效果或鼠标悬停/鼠标悬停效果?
- python - 如何在数组python中均匀分布值
- sympy - SymPy:求解多个方程并根据特定变量显示结果