证明我的问题的假设情况:构建一个允许艺术家创建“专辑”并为这些专辑添加“歌曲”的网络应用程序。 当用户将歌曲广告到相册时,我希望该相册显示在最近更新的相册列表中。
问题:虽然我认为可能,但我不确定如何在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是否可行。我最终只需要专辑的title
和id
,然后我可以从那里构建我需要的一切。
这是最好的方法吗?
数据库是Postgres
答案 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