2016-05-26 76 views

risposta

7

Per trovare il user con min proprietà si può si mply fare,

User.joins(:properties).group("properties.user_id").order("count(properties.user_id) desc").last 

E per trovare le user con max proprietà,

User.joins(:properties).group("properties.user_id").order("count(properties.user_id) desc").first 

Nota: perché è un'operazione di join con properties, così user senza properties non apparirà in questa query.

5

Si potrebbe utilizzare counter_cache.

L'opzione :counter_cache può essere utilizzata per rendere più efficiente la ricerca del numero di oggetti appartenenti.

Da here

belongs_to :user, counter_cache: true 

Quindi creare la migrazione:

def self.up 
    add_column :users, :properties_count, :integer, :default => 0 

    User.reset_column_information 
    User.find(:all).each do |u| 
    User.update_counters u.id, :properties_count => u.properties.length 
    end 
end 

Quindi è possibile prendere utente, che hanno max properties_count

User.maximum("properties_count") 

Ecco un impressionante RailsCast su counter_cache

4

Penso che si possa fare in questo modo per scopi

class User 
    has_many :properties 
    scope :max_properties, 
    select("users.id, count(properties.id) AS properties_count"). 
    joins(:properties). 
    group("properties.id"). 
    order("properties_count DESC"). 
    limit(1) 

    scope :min_properties, 
    select("users.id, count(properties.id) AS properties_count"). 
    joins(:properties). 
    group("properties.id"). 
    order("properties_count ASC"). 
    limit(1) 

E basta chiamare User.max_properties e User.min_properties

aggiornamento:

Sarà aslo lavoro come Borama suggeted

class User 
    has_many :properties 
    scope :max_properties, 
    select("users.*, count(properties.id) AS properties_count"). 
    joins(:properties). 
    group("users.id"). 
    order("properties_count DESC"). 
    limit(1) 

    scope :min_properties, 
    select("users.*, count(properties.id) AS properties_count"). 
    joins(:properties). 
    group("users.id"). 
    order("properties_count ASC"). 
    limit(1) 
+0

Penso che dovresti raggruppare per 'users.id' e non' properties.id' perché funzioni. Inoltre, puoi selezionare 'utenti. *' Invece di solo 'id' in modo che l'utente restituito sia utilizzabile come un normale record di rotaie con tutti gli attributi. – BoraMa

+1

@BoraMa, @Thorin puoi raggruppare per 'users.id' e selezionare solo' users.id' invece 'utenti. *' Perché 'utenti. *' Supportano solo in 'mysql'. 'PG' non consente di selezionare colonne diverse dalla colonna di gruppo e dalla funzione di aggregazione –