2016-12-25 4 views
0

Die DB Beziehung mit:Optimieren einer Abfrage in Schienen Modelle aktiven Datensatz Schienen

Class User < ActiveRecord::Base 
    has_many :user_messages 
    has_many :messages 
end 

Class UserMessage < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :message 
end 

Class Message < ActiveRecord::Base 
    belongs_to :user 
    has_many :user_messages 
end 

Ich möchte den folgenden Code optimieren:

ids.each do |id| 
    user = User.find_by_id(id) 
    unread_count = user.user_messages.where(:folder => user.inbox_id, :read => false).count 
    puts "UserID #{id} ---- Unread Message count #{unread_count}" 
end 

Können einige mir sagen, wie kann ich den obigen Code optimieren Verwenden von Active Record oder SQL Query. Im Grunde möchte ich DB-Abfragen und Zeit reduzieren, die der obige Code braucht, um die Schleife abzuschließen.

Vielen Dank im Voraus.

+0

Klingt wie ein Job für eine linke mit einer Gruppe beitreten durch und zählen. Hast du versucht, ein grundlegendes Tutorial zu SQL zu machen? – Shadow

+0

sollten Sie eine 'unread_count' Spalte in' user' Tabelle speichern, um 'unread_count' für jeden Benutzer zu speichern. – Thanh

+0

Thanh Ich kann die Unread_Count in Benutzertabellen speichern, da ich Massendaten in die Tabelle user_messages mit dieser Model.import-Methode einfüge. – user1969191

Antwort

1

Sie können etwas tun:

users = User.where(id: ids).includes(:user_messages) 
users.each do |user| 
    unread_count = user.user_messages.where(:folder => user.inbox_id, :read => false).count 
    puts "UserID #{user.id} ---- Unread Message count #{unread_count}" 
end 

Da Sie eifrig Laden user_messages, sind, wird es keine andere DB-Abfrage innerhalb der Schleife abzufeuern. Nur 1 Abfrage zum Abrufen des Benutzers und dessen user_messages.

Oder Sie können wie etwas tun:

user_messages = UserMessage.joins(:user).where('folder = users.inbox_id AND read = false').group(:user_id).count 
# user_messages = {1=>10, 2=>19} 
# Here keys are user ids and values are no of user_messages for that user 

user_messages.each do |user_id,unread_msg_count| 
    puts "UserID #{user_id} ---- Unread Message count #{unread_msg_count}" 
end 

PS: ich keinen Code getestet haben, kommentieren Sie bitte einen Fehler, wenn Sie welche haben. Und ich hier angenommen puts "UserID #{ids} Sie einen einzelnen Benutzer-ID setzen wollen und modifiziert meinen Code nach ihm, da in Ihrem Code wird es alle ids ids drucken.

Verwandte Themen