简体   繁体   中英

Rails Order by Contained Objects 2 Levels Deep?

How can I include ordering in an 'order' ActiveRelation call that's more than one level deep?

That is, I understand the answer when it's only one level deep (asked and answered at Rails order by associated data ). However, I have a case where the data on which I want to sort is two levels deep.

Specifically, in my schema a SongbookEntry contains a Recording, which contains an Artist and a Song. I want to be able to sort SongbookEntry lists by song title.

I can go one level deep and sort Recordings by song title:

@recordings = Recording.includes(:song).order('songs.title')

...but don't know how to go two levels deep. In addition, it would be great if I could sort on the recording (that is, the song title and the artist name) -- is this possible without descending into SQL?

Thanks for any help,

Keith

我建议将歌手姓名(可能还有歌曲名称)存储在录音本身上,因此您不必“降级到SQL”。

Try this
SongbookEntry.includes(:recording=>[:artist,:song]).order('songs.title, artists.name')

You can use joins in place of includes if you don't want to use associated tables fields in views

If you model the association between SongbookEntry and Song as such:

class SongbookEntry < ActiveRecord::Base
  # ...
  has_one :song, through: :recording
end

you will be able to access @songbookentry.song and SongbookEntry.joins(:song) using your existing schema.

Edit:

Applying the same idea for Artist , a possible query would be:

SongbookEntry.joins(:song,:artist).order('songs.title','artists.name')

Note that this may not be the most efficient operation (multiple joins involved) even though it looks Rails-ish, so later on you may want to denormalize the tables as Ryan suggested, or find another way to model the data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM