Rails: сравнение статуса с статусом не выполнено

Мне нужно получить все текущие статусы current_user.friends, а затем отсортировать их по created_at.

class User < ActiveRecord::Base
 has_many :statuses
end

class Status < ActiveRecord::Base
 belongs_to :user
end

И в контроллере:

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 возвращает массив объектов User

friend.statuses возвращает массив объектов Status

Ошибка:

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

Ответы

Ответ 1

У меня была аналогичная проблема, решаемая с помощью метода to_i, но не могу объяснить, почему это происходит.

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

Кстати, это сортирует в порядке убывания. Если вы хотите по возрастанию:

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

Ответ 2

Это сообщение об ошибке появляется, когда sort получает нуль, возвращаемое из <= > . <= > может возвращать -1, 0, 1 или ноль, но сортировка не может обрабатывать nil, потому что для сопоставления всех элементов списка необходимо сопоставить.

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

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

Один из способов отладки этой ошибки - проверить, является ли возврат вашего <= > равным нулю и вызывает исключение, если оно есть.

@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

Ответ 3

У меня была аналогичная проблема сегодня в групповом проекте. Этот ответ не разрешил его, но в чем была наша проблема, кто-то положил другие модели. Новый в нашем Def show User controller. Например...

Class UsersController < ApplicationController

def show

    @status = @user.statuses.new

end

Это создало конфликт между @user.statuses и @status, который я пытался вызвать на странице. Я снял с себя пользователя и просто сделал...

def show

    @status = Status.new

end

И это сделало трюк для меня.