lin*_*ndy 3 ruby activerecord ruby-on-rails
我有以下关联:Artist has_many Songs.因此,我可以通过以下方式获得艺术家的歌曲:
artist.songs
Run Code Online (Sandbox Code Playgroud)
但是,我想只获得歌曲的类型:
artist.songs.pluck(:genre)
Run Code Online (Sandbox Code Playgroud)
但是,这种类型可能会在结果中出现多次; 我只想获得独特的流派价值观.不幸的是,pluck这里没有任何帮助,因为它返回一个数组,并且调用uniq它不会调整ActiveRecord查询,但是普通的Array#uniq.
我可以这样做:
artist.songs.select(:genre).uniq.pluck(:genre)
Run Code Online (Sandbox Code Playgroud)
但我觉得必须有更好的方法.
PS:然而,从一些最小的基准测试来看,pluck + Array#uniq似乎要快一些select + uniq + pluck.
如果使用艺术家的songs关联,您可以select distinct打开genre,然后映射结果以返回字符串:
artist.songs.select('distinct genre').map(&:genre)
# or...
artist.songs.select(:genre).uniq.map(&:genre) # uniq or distinct work
Run Code Online (Sandbox Code Playgroud)
结果查询:
(0.2ms) SELECT distinct genre FROM "songs" WHERE "songs"."artist_id" = ? [["artist_id", 1]]
如果在缩小到艺术家的同时直接调用Song模型,您也可以使用uniq:
Song.where(artist: artist).uniq.pluck(:genre)
结果查询:
(0.2ms) SELECT DISTINCT "songs"."genre" FROM "songs" WHERE "songs"."artist_id" = 1
两者都是同等有效的,并且在SQL中执行唯一性操作,而不是在Ruby中.
| 归档时间: |
|
| 查看次数: |
2871 次 |
| 最近记录: |