0

在我的一个模型中,我将相等定义为也可以处理字符串和符号。一个角色等于另一个角色(或字符串或符号),如果其名称属性相同:

class Role
  def == other
    other_name = case other
                 when Role then other.name
                 when String, Symbol then other.to_s
                 end
    name == other_name
  end
end

平等检查工作正确:

role = Role.create name: 'admin'
role == 'admin' # => true
role == :admin  # => true

但是当我Role在 has_many 关系中使用模型时,在我得到的集合中,include?不承认这种平等:

user = User.create
user.roles << role
User.roles.include? role    # => true
User.roles.include? 'admin' # => false 
User.roles.include? :admin  # => false

为了使这项工作,我必须明确地将其转换为数组:

User.roles.to_a.include? 'admin' # => true
User.roles.to_a.include? :admin  # => true

所以很明显,Rails 覆盖了include?返回的数组中的方法user.roles。这很糟糕并且与 ruby​​s规范相反Enumerable#include?(其中明确指出,“Equailty 是使用测试的==”)。这不适用于我从中获得的数组user.roles==甚至从未被调用。

这个修改后的行为在哪里include?指定?

还有其他方法可以测试我错过的包含吗?还是我必须每次都使用to_a或实际实例?Role

4

1 回答 1

0

您没有正确实现相等运算符。它应该是:

def == other
  other_name = case other
    when Role then other.name
    when String, Symbol then other.to_s
  end
  name == other_name
end
于 2013-05-20T15:57:18.587 回答