Rails Active Record - 最近通过协会更新

时间:2017-05-11 13:36:08

标签: ruby-on-rails postgresql activerecord

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

问题:虽然我认为可能,但我不确定如何在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歌曲的所有专辑?已发行的歌曲是一首出现的歌曲&lt; = NOW()。

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

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

这是最好的方法吗?

数据库是Postgres

1 个答案:

答案 0 :(得分:0)

添加新歌后,使用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