2017-09-27 1 views
0

Ich habe zwei Modelle, eine User und eine Exercise wo ein Benutzer has_many :exercises. Es gibt einen cache_counter auf dem Modell User, exercise_countAbfrage verschachtelte Anzahl

Ich möchte eine Rangliste basierend auf einer Trainingsanzahl des Benutzers im aktuellen Monat erstellen. Ich möchte die 2 Benutzer mit den höchsten Trainingszählungen des Monats zusammen mit der Zählung anzeigen. Wenn es andere Benutzer gibt, die die gleiche Trainingsanzahl wie der zweite Benutzer haben, möchte ich sie auch anzeigen. (Display 2+ Benutzer)

Die aktuelle Abfrage Ich habe,

# User model 
scope :exercises_this_month, -> { includes(:exercises).references(:exercises) 
    .where("exercise_count > ? AND exercises.exercise_time > ? AND exercises.exercise_time < ?", 
    0 , Time.now.beginning_of_month, Time.now.end_of_month) 
} 

def User.leaders 
    limit = User.exercises_this_month.where("exercise_count > ?", 0).order(exercise_count: :desc).second.exercise_count 
    User.exercises_this_month.where("exercise_count > ? AND exercise_count >= ?", 0, limit) 
end 

das oben 2+ Benutzerobjekt für alle Zeit zurückzukehren. Ich möchte dies auf den aktuellen Monat beschränken.

Antwort

1

Sie können den counter_cache hier nicht verwenden, da er die Nummer von allen Zeiten speichert. Ein anderes Problem, das Sie haben, ist, dass Sie diejenigen mit der zweithöchsten Zahl vermissen, wenn Sie mehrere Spieler mit der gleichen Anzahl an Übungen haben.

# Exercise.rb 
scope :exercises_this_month, -> { 
    where("exercises.exercise_time > ? AND exercises.exercise_time <= ?", 
    Time.now.beginning_of_month, Time.now.end_of_month) 
} 

#User.rb 
players_this_month = User.joins(:exercises).group(:user_id).merge(Exercise.exercises_this_month).count ## 

sorted_counts = players_this_month.values.uniq.sort 

if sorted_counts.present? 
    second_place_counts = sorted_counts[-2] || sorted_counts[-1] #in case all have the same number 
    top_two_ids = players_this_month.map { |k,v| k if v >= second_place_counts } ##user ids with top two numbers 
end 
+0

Ich landete mit dem Wesen dieser Antwort und erstellt auf dem Übungsmodell einen Umfang genießen durch zu begrenzen Monat, dann erstellt ein Array von Benutzern durch diese zählt und die Top-Benutzer von dort ausgewählt – Andy

0
gem 'groupdate' 
    model 
    def self.by_month(month_num) 
     self.where("cast(strftime('%m', created_at) as int) = # 
     {Date.today.strftime("%m")}") 
    end 
    controller 
     def report 
     @posts =Post.by_month(Date.today.strftime("%m")) 
     end 
    view 
    some think like this 
     = @posts.group_by_month(:created_at).count 

Ich bin nicht sicher, was Sie wollen, aber das wird hoffentlich große Hilfe :)