2013-05-20 27 views
0

在我的一个模型中,我定义了相等也可以使用字符串和符号。角色是等于另一个角色(或字符串或符号),如果它的name属性是一样的:在has_many关系中,在返回的集合中包含?不承认平等

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 

为了使这项工作,我必须明确地CONVER吨这对的数组:

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

因此很明显的Rails覆盖由user.roles返回的数组中的include?方法。这很糟糕,并且与Enumerable#include?(明确指出“EQUALTY使用==进行了测试”)的ruby specification相反。对于我从user.roles获得的数组,这不是真的。 ==从未被称为。

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

是否有另一种方法来测试我错过了包含?或者我每次都必须使用to_aRole的实际实例吗?

+0

这是什么:'User.roles.class'在你的控制台? –

+0

@grotori:user.roles.class#=>数组 – Conkerchen

回答

0

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

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

这只是一个错误(相应更新)的错字。正如我所说的,检查平等通常是有效的,除了'include?',它甚至没有被使用。 – Conkerchen

+0

我在我的模型中试过你的代码,纠正了相等运算符并包含了?工作很好... –

+0

我刚开始一个新项目,只是为了仔细检查。但它仍然不适用于我。我更新到最新的钢轨版本3.2.12,仍然是一样的。很奇怪......你确定,你在has_many关系内尝试过它,而不是在任意数组上?例如'[Role.create(name:'test'),Role.create(name:'test_2')]。include? 'test'将按预期工作,但是'user.roles.include? 'test''不会。 – Conkerchen