ruby-on-rails - 仅查找所有 has_many 集合都具有特定列值的对象

标签 ruby-on-rails postgresql activerecord relational-division

我有一个Album对象,其中有许多Tracks。轨道有一个 youtube_uid 列。我想查询包含所有轨道 youtube_uids 的专辑。我知道查找包含轨道的专辑的技术,其中至少有一首轨道带有 youtube_uid:

Album.left_outer_joins(:tracks).where.not(tracks: { youtube_uid: nil })

查找每首轨道都有 youtube_uid 的专辑的理想查询是什么?

最佳答案

据我了解您的问题,您想要查找所有没有缺少(空)youtube-uid 轨道的专辑。所以据我所知,您需要一个 NOT EXISTS 查询。

在sql中我会写一些类似的东西

 select * from albums a
 where not exists (select * from tracks where album_id = a.id and youtube_uid is null) 

那么我们如何最好地将其转换为 activerecord?我看到两种可能性:

 sql = <<-SQL
   select * from albums a
   where not exists (select * from tracks where album_id = a.id and youtube_uid is null) 
 SQL

 Album.find_by_sql(sql) 

虽然这可行,而且对于我来说对 SQL 很熟悉,这感觉很好,它不是很“像 Rails”,所以我们可以改进它吗?

有一个更短的形式:

Album.where("not exists (select * from tracks where album_id = albums.id and youtube_uid is null")

但这仍然感觉有点太冗长了。 幸运的是,存在一种更像 Rails 的方式。在 Rails 4 中你可以这样写:

  Album.where(Track.where("album_id = albums.id").where(youtube_uid: nil).exists.not)

在 Rails 5/6 中,这不再可能,你必须编写:

  Album.where(Track.where("album_id = albums.id").where(youtube_uid: nil).arel.exists.not)

您可以通过在末尾添加 to_sql 轻松验证这会生成正确的 sql。

关于ruby-on-rails - 仅查找所有 has_many 集合都具有特定列值的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63599068/

相关文章:

ruby-on-rails - 如何使用回调更新另一个模型?

ruby-on-rails - 将 cache_digests 与 XML 构建器一起使用?

mysql - 无法在 Windows 7 64 位上安装 openproject - Fiddle :Module 的未定义方法 `dlopen'

postgresql - 选择将具有范围的行拆分为具有较小范围的几行?

postgresql - 是否可以使用 UPDATE 中的 RETURNING 子句作为 INSERT 查询子句的查询子句?

ruby-on-rails - rails : check if the model was really saved in after_save

ruby-on-rails - 为什么不能使用名为 "action"的参数?

mysql - 在 JRuby 上使用 ActiveRecord 对 MariaDB 的首次查询需要 5 分钟以上才能执行

json - 无法修复 Active Record 挂起的迁移错误

postgresql - 使用 NHibernate 映射复合键时出现问题(列已添加)