mysql - रेल 3 ActiveRecord: एसोसिएशन पर गिनती द्वारा आदेश



ruby-on-rails ruby-on-rails-3 (2)

इससे भी बेहतर, 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 बजाए कक्षा विधि का उपयोग करना scope

def self.top
    select('comments.*, COUNT(listens.id) AS listens_count').
      joins(:listens).                                                   
      group('comments.id').
      order('listens_count DESC').
      limit(5)
end

मेरे पास Song नाम का एक मॉडल है। मेरे पास Listen नाम का एक मॉडल भी है। एक Listen belongs_to :song , और एक गीत :has_many listens (कई बार सुन सकते हैं)।

मेरे मॉडल में मैं एक विधि self.top को परिभाषित करना चाहता self.top जो शीर्ष 5 गीतों को सबसे ज्यादा सुनना चाहिए। मैं has_many संबंध का उपयोग कर इसे कैसे प्राप्त कर सकता हूं?

मैं रेल 3.1 का उपयोग कर रहा हूँ।

धन्यवाद!


Answer #1

रेल के लिए 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")
  }




activerecord