2010-01-07 46 views
37

Sé que he visto esto antes, pero ahora no puedo encontrar nada. Quiero agrupar una consulta en una determinada columna y poder mostrar cuántos hay en cada grupo. Tengo la primera parte de abajo:Agrupar y contar en Rails

@line_items = @project.line_items.all(:group => "device_id") 

Esto es para la línea de pedido vista de índice, que es sólo una tabla que muestra los elementos de línea. ¿Cómo puedo hacer una columna en esa tabla para "contar" ahora que las líneas de pedido están agrupadas por dispositivo?

Respuesta

75

Puede hacer count en line_items que le devolverá un hash ordenado de device_id y count.

@project.line_items.group(:device_id).count 
+1

Esto da una advertencia: 'ADVERTENCIA DE DEPRESIÓN: el número de relación calculado con las opciones del buscador está en desuso. Construya un ámbito y luego llame a calcular en su lugar. (llamado desde C: en 'conteo' :) ' – Chloe

+6

@Chloe - Pruebe esto en Rails 4 para eliminar la advertencia:' @ project.line_items.group (: device_id) .count' –

8

Sólo añadir una opción de :select:

@line_items = @project.line_items.all(
    :group => "device_id", 
    :select => "device_id, COUNT(*) as count" 
) 

Luego, cada @line_item tendrá un atributo count.

+0

gestión de recursos humanos, que ponen de depuración (@line_items) en mi opinión, pero aún no hay cargos, por lo que don' Creo que te estoy entendiendo. Creo que la salida es exactamente la misma que sin la opción de seleccionar. – tladuke

+0

esto realmente funciona, pero no si tiene: incluya – tladuke

+0

El método de depuración no mostrará el recuento porque no es un atributo de ActiveRecord, pero * hay * un atributo de recuento en cada objeto. En cualquier caso, la solución de Chandra es mucho mejor. –

10

hash del devise_id como llave y registros asociados se consideran

@project.line_items.group(:devise_id).count 
3

algo así como

User.all(:joins => :comments, :select => "users.*, count(comments.id) as comments_count", :group => "users.id") 

también podría funcionar ...

0

Sólo para contar despluma sería más rápido aquí en vez de grupo

@project.line_items.pluck(:device_id).count 


@project.line_items.pluck(:device_id).uniq.count 
+0

Devolverán resultados completamente diferentes para los atributos enumerados . Por ejemplo: 'customer_subscriptions.group (: status) .count' devolverá: ' {1 => 6, 2 => 11, 3 => 136, 0 => 30} ' y' customer_subscriptions. despluma (: estado) .count' simplemente devolverá '183' – msdundar

+0

cierto, ¿qué hay de uniq entonces? @ project.line_items.pluck (: device_id) .uniq.count –

0

Creo que se puede probar este también.

@project.line_items.group(:device_id).pluck("device_id, count(device_id)") 

^^ Esto da matriz de matrices con device_id 'y el recuento de' elementos