gpt4 book ai didi

ruby-on-rails - 自身具有多个条件和嵌套属性的 Rails Scope

转载 作者:行者123 更新时间:2023-12-04 18:01:55 27 4
gpt4 key购买 nike

在我的 Rails 应用程序中,类 Project 定义如下:

has_many :spins
has_one :video

我想为 Project 创建一个范围,它返回满足以下条件的所有项目:

project.video.present? || project.spins.count > 0 && project.spins.first.default_video.present?

我读过如何使用 multiple conditions在一个范围内,但我不确定如何将其与嵌套属性(在本例中为自旋)的条件相结合。

如何为满足这些条件的项目创建范围?

编辑:为了澄清,default_video 是 Spin 的类方法:

def default_video
self.videos.where("has_audio IS NULL").first
end

最佳答案

据我所知,ActiveRecord 不提供使用 OR 合并作用域的功能(暂时)。我认为有两种选择可以处理此功能:

1 - 创建一个范围,返回包含视频的项目或第一次旋转包含默认视频的项目:

scope :with_video, -> { joins(
'LEFT JOIN spins
ON spins.id = (
select p.id
from spins as p WHERE projects.id = p.project_id ORDER BY p.id LIMIT 1
)
JOIN videos on videos.project_id = projects.id
WHERE
spins.default_video IS NOT NULL
OR
videos.project_id IS NOT NULL
')

我认为这个解决方案不可读且难以维护。我没有对这个查询做一些性能测试,也许这个必须改进

2 - 创建 2 个范围并合并两个结果

scope :with_one_video, -> { joins(:videos) }
scope :with_spin_video, -> { joins('JOIN spins ON
spins.id = (
SELECT S.id
FROM spins as S
WHERE projects.id = S.project_id
ORDER BY S.id LIMIT 1
)').where('spins.default_video IS NOT NULL')}

def with_video
(with_one_video.to_a + with_spin_video.to_a).uniq
end

这个对于可重用范围更好,但第二个范围仍然难以阅读。使用此解决方案,结果已作为数组返回,这可能是一个缺点,具体取决于情况。

编辑:我对所有具有不同解决方案的答案、对 sql 查询的改进甚至用 activerecord/arel 替换它们都很感兴趣

关于ruby-on-rails - 自身具有多个条件和嵌套属性的 Rails Scope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33886476/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com