运行specs时,会出现以下错误:

.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activemodel-4.2.5/lib/active_model/validations/callbacks.rb:26: warning: Comparable#== will no more rescue exceptions of #<=> in the next release.
.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activemodel-4.2.5/lib/active_model/validations/callbacks.rb:26: warning: Return nil in #<=> if the comparison is inappropriate or avoid such comparison.

我唯一的地方是在我的模型中:
class PostCategory
  CONTEXTS = %w(regular)

  module Collections
    def all
      @all ||= AppConfig.post_categories.
       map { |c| new(c) }.
       sort
    end

    def in_context(context)
      @all.select { |e| e.in_context?(context) }
    end
  end

  extend Collections

  include Comparable

  attr_reader :name, :image_id

  def initialize(hash)
    @name          = hash.fetch('name')
    @image_id      = hash.fetch('image_id')
    @contexts      = hash.fetch('contexts', CONTEXTS)
  end

  def <=>(other)
    @name <=> other.name
  end
end

我试着在“def(other)”后面添加nil,但这会给排序带来问题。

最佳答案

出现此警告的原因是您可以在this Ruby issue中看到讨论的更改。其要点是:当一个类包含Comparable并调用其==方法时,Comparable#==依次调用<=>方法到目前为止,在Ruby的版本中,如果<=>引发了一个错误,==将吞下该错误并返回false这是好的,因为开发人员不希望==引发错误,但这是坏的,因为它可以隐藏<=>的问题在以后的版本中,==将不再接受由<=>引发的错误,因此出现警告。
如果查看堆栈跟踪中提到的行上的Rails source,可以看到错误的来源:

define_callbacks :validation,
                 terminator: ->(_,result) { result == false },
                 # ...

在您的例子中,result是您的postcategy类的一个实例当上面的第二行调用result == false时,<=>方法调用false.name,这会引发一个错误(因为false不响应name)。
解决方法是按照Comparable docs的说法:
如果另一个对象不可比较,则<=>运算符应返回nil
修改你的方法如下:
def <=>(other)
  return unless other.respond_to?(:name)
  @name <=> other.name
end

或者,如果您希望postcategy的实例只与postcategy的其他实例相比较(与响应name的任何实例相反):
def <=>(other)
  return unless other.is_a?(self.class)
  @name <=> other.name
end

关于ruby-on-rails - 运行测试时的弃用问题:Comparable#==将不再有#<=>的救援异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34584461/

10-12 05:16