当我运行规范时,出现以下错误:
.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 returnnil
.
像这样修改你的方法:
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/