0
好的,所以我有這個Concern
其中包含一個方法top
用於檢索記錄順序的次數由某人已經聆聽他們(如果該記錄是一首歌曲,直接或通過歌曲,如果它是別的東西,如流派或藝術家)。如果是平局,則按其他網站上的受歡迎程度排序記錄。如何將此SQL轉換爲ActiveRecord查詢?
以下代碼幾乎完美地工作。它以正確的順序返回一個對象數組。我的主要問題是我得到一個數組而不是一個關係。因此,來電者不能再添加諸如Song.top.limit 3
或Genre.top.offset(10).limit(5)
之類的內容。
這裏是我的方法:
def top(options = {})
tname = self.name.tableize
inner_select = self.select("#{tname}.*,COUNT(DISTINCT(listens.id)) AS listens_count")
inner_select = inner_select.joins(:songs) unless self.name == 'Song'
inner_select = inner_select.joins("LEFT JOIN listens ON listens.song_id = songs.id")
inner_select = inner_select.where("listens.user_id = ?", options[:for].id) if options[:for].is_a? User
inner_select = inner_select.group("#{tname}.id").to_sql
# this is the part that needs fixin'
find_by_sql("
SELECT
#{tname}.*,
#{tname}.listens_count,
SUM(sources.popularity) AS popularity_count
FROM (#{inner_select}) AS #{tname}
LEFT JOIN sources ON
sources.resource_id = #{tname}.id
AND
sources.resource_type = '#{self.name}
GROUP BY #{tname}.id
ORDER BY listens_count DESC, popularity_count DESC
")
end
下面是生成,按要求SQL查詢。這是Song.top
:
SELECT
songs.*,
songs.listens_count,
SUM(sources.popularity) AS popularity_count
FROM (SELECT songs.*,COUNT(DISTINCT(listens.id)) AS listens_count FROM "songs" LEFT JOIN listens ON listens.song_id = songs.id GROUP BY songs.id) AS songs
LEFT JOIN sources ON
sources.resource_id = songs.id
AND
sources.resource_type = 'Song'
GROUP BY songs.id
ORDER BY listens_count DESC, popularity_count DESC
這是Artist.top
:
SELECT
artists.*,
artists.listens_count,
SUM(sources.popularity) AS popularity_count
FROM (SELECT artists.*,COUNT(DISTINCT(listens.id)) AS listens_count FROM "artists" INNER JOIN "artists_songs" ON "artists_songs"."artist_id" = "artists"."id" INNER JOIN "songs" ON "songs"."id" = "artists_songs"."song_id" LEFT JOIN listens ON listens.song_id = songs.id GROUP BY artists.id) AS artists
LEFT JOIN sources ON
sources.resource_id = artists.id
AND
sources.resource_type = 'Artist'
GROUP BY artists.id
ORDER BY listens_count DESC, popularity_count DESC
它可能是有點容易(從日誌,或使用'to_sql') – IS04 2014-08-27 20:28:08