2012-08-22 24 views
15

Necesito obtener todos los estados del usuario_actual.amigos y luego ordenarlos por created_at.Rieles: la comparación del estado con el estado falló

class User < ActiveRecord::Base 
has_many :statuses 
end 

class Status < ActiveRecord::Base 
belongs_to :user 
end 

Y en el controlador:

def index 
    @statuses = [] 
    current_user.friends.map{ |friend| friend.statuses.each { |status| @statuses << status } } 
    current_user.statuses.each { |status| @statuses << status } 

    @statuses.sort! { |a,b| b.created_at <=> a.created_at } 
end 

current_user.friends devuelve una matriz de objetos User

friend.statuses devuelve una matriz de objetos Status

Error:

comparison of Status with Status failed 
app/controllers/welcome_controller.rb:10:in `sort!' 
app/controllers/welcome_controller.rb:10:in `index' 
+1

su problema central pero caminar todas esas asociaciones le matará por el gran número de consultas. Agarrar a todos los amigos y todos sus estados y luego ordenarlos en código puede generar una cantidad impía de consultas, tu rendimiento disminuirá rápidamente. ¿Por qué no simplemente escribir una sola consulta SQL que pueda buscar y ordenar todos esos registros a la vez? –

+0

Gracias, encontré una manera fácil y efectiva: 'Status.where (user_id: current_user.friends.map (&: id) .insert (0, current_user.id)). All' ¿qué opinas? – Alex

Respuesta

16

Tuve un problema similar, resuelto con el método to_i, pero no puedo explicar por qué sucede eso.

@statuses.sort! { |a,b| b.created_at.to_i <=> a.created_at.to_i } 

Por cierto, esto se ordena en orden descendente. Si desea una orden ascendente es:

@statuses.sort! { |a,b| a.created_at.to_i <=> b.created_at.to_i } 
+20

"error de comparación de X con X" se desencadena por 'nil' en cualquier lado de' <=> '. Al agregar la conversión '.to_i' has convertido nils en 0s y eso curó el problema. –

+0

¡agradable! En mi caso, debería ser imposible obtener 'nil' en esta parte del código ... tal vez sea un error, comenzaré a registrarlo. ¡Gracias! – hsgubert

+1

Serge - debe poner eso como una respuesta, y debe ser aceptado, ya que en realidad responde a la pregunta del título ... –

1

Tuve un problema similar esta noche en un proyecto de grupo. Esta respuesta no lo resolvió, pero cuál era nuestro problema, alguien puso otros modelos.nuevo en nuestro controlador de usuario def show. Por ejemplo ...

Class UsersController < ApplicationController 

def show 

    @status = @user.statuses.new 

end 

Esta fue la creación de un conflicto entre los user.statuses @ y el @status yo estaba tratando de obtener de la página. Me quité el usuario y acabo de ...

def show 

    @status = Status.new 

end 

Y eso me sirvió de algo.

4

Este mensaje de error aparece cuando se devuelve un valor cero desde < =>. < => puede devolver -1, 0, 1 o nil, pero sort no puede manejar nil porque necesita que todos los elementos de la lista sean comparables.

class A 
    def <=>(other) 
    nil 
    end 
end 

[A.new, A.new].sort 
#in `sort': comparison of A with A failed (ArgumentError) 
# from in `<main>' 

Una forma de depurar este tipo de error es comprobando si la devolución de su => es nula < y lanzar una excepción si lo es.

@statuses.sort! do |a,b| 
    sort_ordering = b.created_at <=> a.created_at 
    raise "a:#{a} b:#{b}" if sort_ordering.nil? 
    sort_ordering 
end 
No
Cuestiones relacionadas