【问题标题】:Rails Active Record - Recently Updated Through AssociationRails Active Record - 最近通过关联更新
【发布时间】:2017-05-12 17:52:08
【问题描述】:

演示我的问题的假设情况:构建一个网络应用程序,允许艺术家创建“专辑”并将“歌曲”添加到这些专辑中。 当用户将歌曲广告到专辑时,我希望该专辑显示在最近更新的专辑列表中。

问题:我不确定如何在 Active Record 中编写此查询,尽管我认为它是可能的。

示例:如果将一首新歌添加到专辑中,那么我希望在结果集中返回该专辑。最终我想要的结果是一组专辑,但该组取决于其更新的子项的类型——歌曲。

换一种说法 - 我希望有人能够访问网页并查看最近更新的所有专辑(更新是在专辑中添加新歌曲时)。

类:

class User < ActiveRecord::Base
  has_many :songs
end 

class Song < ActiveRecord::Base
  belongs_to :user
  has_many :album_songs
  has_many :albums, :through => :album_songs

  # has a release_date field too, which is when the song will be released.
end

class AlbumSong < ActiveRecord::Base
  belongs_to :song
  belongs_to :album
end 

class Album < ActiveRecord::Base
  has_many :album_song
  has_many :songs, :through => :album_song
end 

如何编写查询以返回最近添加了 RELEASED 歌曲的所有专辑?发行的歌曲是

需要考虑的其他事项。如果用户将三首歌曲添加到他们的专辑中,我只希望该专辑在列表中显示一次,而不是三次,如果歌曲已发布。如果歌曲尚未发布,则查询不应返回已更新的该课程。每次添加发布的歌曲时,课程都会在“最近更新”列表中上移。因此我需要一些独特的东西(我认为)。

我不确定这对于 ActiveRecord 是否可行。我最终只需要专辑的titleid,然后我就可以从那里构建我需要的一切。

最好的方法是什么?

数据库是 Postgres

【问题讨论】:

  • 这是一个概念性问题,您的应用可以在添加歌曲时更新您的users.updated_at 字段吗?
  • @AlejandroMontilla 不,由于其他业务原因,我们无法更新。
  • users 添加一列来管理这也不是一种选择?
  • @AlejandroMontilla 它不起作用,因为我还需要基于日期字段(release_date)的查询,这是基于时间的。

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

添加新歌曲后,使用touch 更新专辑的 updated_at 字段:

class AlbumSong < ActiveRecord::Base
  belongs_to :song
  belongs_to :album, touch: true
end

然后,您可以使用此查询来获取 10 个最近更新的专辑:

Albums.order(updated_at: :desc).limit(10)

更新

要获得按最后添加的歌曲(已发布)排序的 10 张专辑,您可以试试这个范围:

class Album < ActiveRecord::Base
  ...

  scope :sorted_by_recent_song, -> {
    joins(:albums_songs)
    .where('
      albums_songs.updated_at = (
        SELECT MAX(albums_songs.updated_at)
        FROM albums_songs
        JOIN songs ON albums_songs.song_id = songs.id
        WHERE albums_songs.album_id = albums.id
        AND songs.release_date <= NOW()
      )
    ')
    .group(['albums.id', 'albums_songs.id'])
    .order('albums_songs.updated_at DESC')
    .limit(10)
  }
end

【讨论】:

  • 天哪,差不多了。我完全忘了包括我需要过滤歌曲类的 release_date 字段。我已经更新了我的问题。不过谢谢你!
  • @DonnFelker 我刚刚更新了我的答案。你能看看吗? :)
  • 按原样运行此查询,给我一个错误,声称我来自 albums 的 from 子句条目丢失。如果我添加以下联接,查询将执行但只返回 1 条记录:JOIN albums ON albums_songs.album_id = albums.id
  • 好的,越来越近了。我删除了MAX 并将.updated_at = ( SELECT... 更改为.updated_at IN (SELECT ...,现在我得到了10 个结果,但我看到的是重复的专辑而不是正确的专辑。嗯。由于许多歌曲与 updated_at IN 子句匹配,因此专辑也会重复。
  • 在运行我上面发布的范围后,您能告诉我完整的错误(带有查询预览)吗?你确定,你把它放在专辑模型或歌曲模型中吗?抱歉回复晚了。
猜你喜欢
  • 2012-01-01
  • 1970-01-01
  • 2017-10-14
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 1970-01-01
相关资源
最近更新 更多