运行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/