ruby-on-rails - 运行测试 : Comparable#== will no more rescue exceptions of#<=> 时的弃用问题

标签 ruby-on-rails ruby ruby-on-rails-4

当我运行规范时,出现以下错误:

.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是您的 PostCategory 类的一个实例。当上面第二行调用result == false , 你的 <=>方法调用 false.name ,这会引发错误(因为 false 不响应 name )。

解决方案是像Comparable docs那样做说:

If the other object is not comparable then the <=> operator should return nil.

像这样修改你的方法:

def <=>(other)
  return unless other.respond_to?(:name)
  @name <=> other.name
end

或者,如果您希望 PostCategory 的实例仅与 PostCategory 的其他实例进行比较(而不是任何响应 name 的实例):

def <=>(other)
  return unless other.is_a?(self.class)
  @name <=> other.name
end

关于ruby-on-rails - 运行测试 : Comparable#== will no more rescue exceptions of#<=> 时的弃用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34584461/

相关文章:

ruby-on-rails - 使用变量更新 Active Record 的属性

javascript - CSS 动画在 Rails 应用程序中不起作用

ruby-on-rails - rails : updating to non vulnerable version

ruby-on-rails - rails + mongoid : limit fields using only keyword

javascript - Rails 4 Bootstrap 模式在显示前短暂闪烁

ruby-on-rails - 如何在不破坏用户记录的情况下删除用户关联?

ruby-on-rails - 如何从控制台访问 Ruby on Rails Rails.root.join yml 文件?

ruby-on-rails - 在 Ruby 中编译 Assets 是否需要在部署时完成?为什么之前不呢?

css - 应用程序不读取样式表

ruby-on-rails - 唯一性验证不起作用