반응형
레일 3 액티브 레코드:연관 개수별 주문
저는 모델명을 가지고 있습니다.Song
모델도 있어요.Listen
.aListen
belongs_to :song
, 그리고 노래.:has_many listens
(여러 번 들을 수 있습니다).
내 모델에서 메서드를 정의하고 싶다.self.top
가장 많이 들었던 상위 5곡으로 돌아가겠습니다.이 기능을 이용하려면 어떻게 해야 합니까?has_many
관계요?
Rails 3.1을 사용하고 있습니다.
감사합니다!
class Song
has_many :listens
scope :top5,
select("songs.id, OTHER_ATTRS_YOU_NEED, count(listens.id) AS listens_count").
joins(:listens).
group("songs.id").
order("listens_count DESC").
limit(5)
Song.top5 # top 5 most listened songs
더 좋은 것은 사용counter_cache
쿼리에서 하나의 테이블을 사용하기 때문에 더 빠를 수 있습니다.
노래 수업은 다음과 같습니다.
class Song < ActiveRecord::Base
has_many :listens
def self.top
order('listens_count DESC').limit(5)
end
end
그리고 듣기 수업:
class Listen < ActiveRecord::Base
belongs_to :song, counter_cache: true
end
마이그레이션을 추가해야 합니다.
add_column :comments, :likes_count, :integer, default: 0
보너스 포인트, 테스트 추가:
describe '.top' do
it 'shows most listened songs first' do
song_one = create(:song)
song_three = create(:song, listens_count: 3)
song_two = create(:song, listens_count: 2)
popular_songs = Song.top
expect(popular_songs).to eq [song_three, song_two, song_one]
end
end
또는 위의 방법을 사용하고 싶다면, 여기에 조금 더 단순하고, 클래스 방식을 사용하는 것이 좋습니다.scope
def self.top
select('comments.*, COUNT(listens.id) AS listens_count').
joins(:listens).
group('comments.id').
order('listens_count DESC').
limit(5)
end
레일 4.x의 경우 연관성이 없는 행이 중요한 경우 다음과 같이 하십시오.
scope :order_by_my_association, lambda {
select('comments.*, COUNT(listens.id) AS listens_total')
.joins("LEFT OUTER JOIN listens ON listens.comment_id = comments.id")
.group('comments.id')
.order("listens_total DESC")
}
언급URL : https://stackoverflow.com/questions/8696005/rails-3-activerecord-order-by-count-on-association
반응형
'itsource' 카테고리의 다른 글
composition api에서 vuex 모듈 getter를 사용하는 방법 (0) | 2022.09.25 |
---|---|
REST API에 대한 Larabel DB 쿼리가 매우 느립니다. (0) | 2022.09.25 |
MySQL 업데이트가 인덱스 조건 푸시다운을 지원하지 않습니까? (0) | 2022.09.25 |
안쪽을 클릭할 때 드롭다운 메뉴가 닫히지 않도록 합니다. (0) | 2022.09.25 |
디렉토리의 모든 파일을 루프하는 PHP 스크립트? (0) | 2022.09.25 |