Development Tip

Rails 3 ActiveRecord : 연결 횟수 별 주문

yourdevel 2020. 12. 7. 20:59
반응형

Rails 3 ActiveRecord : 연결 횟수 별 주문


라는 모델이 Song있습니다. 라는 모델도 있습니다 Listen. A Listen 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

For rails 4.x try this if your rows without any association matters:

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

반응형