【发布时间】:2009-06-24 13:55:13
【问题描述】:
Rails 的 ActiveRecord::Base 类定义了一个 == 方法,如果对象相同或具有相同的 ID,则返回 true。
我已经在我的几个 Rails 模型中覆盖了==,以允许更有意义的相等条件。当我直接比较对象时(例如,通过script/console),这些工作,但如果我做类似my_array_of_models.include? other_model,include? 总是返回false。即使数组包含一个“相等”的对象(根据我的定义)。
我已经解决了这个问题,例如,my_array_of_models.any? { |el| el.attr == other_model.attr }(我认为这是鼓励您进行比较的方式,无论如何),但我想知道:在 ActiveRecord 中覆盖 == 是否有意义模型,还是 ActiveRecord 做了一些高级别的事情,使这种被覆盖的方法无用(或更糟,危险)?
来源
这是我的重写方法的实现。有两个类,User 和 Contact。 Users 具有唯一的电子邮件地址,因此如果电子邮件地址相同,== 将返回 true。 Contact 是Users 之间的桥梁(就像社交网络中的“朋友”关系),如果它们具有相同的user_id,则应返回true。
class User < ActiveRecord::Base
def ==(other)
other.respond_to?(:email) and self.email == other.email
end
end
class Contact < ActiveRecord::Base
def ==(other)
if other.class == self.class
self.user == other.user
elsif other.kind_of? User
self.user == other
else
false
end
end
end
正如我所指出的,它在直接比较时有效(例如,one_object == another_object),但my_array_of_objs.include? included_obj 总是返回false。
【问题讨论】:
-
当你提到直接比较对象时,我假设你的意思是在 model1 == model2 中。 my_array_of_models.include 吗?当您通过脚本/控制台尝试时,other_model 会按预期工作吗?
-
不,Array.include?无论如何,在我的测试中总是返回 false ——即使是通过脚本/控制台。
-
Hmm.. 这里肯定有其他事情可以通过脚本/控制台进行快速测试,我在 ActiveRecord 子类上覆盖 == 以始终返回真正的线索到 Array.include?只要数组包含 1 个具有覆盖 == 的类型的模型,则始终返回 true。你能发布你的具体 == 实现吗?
-
.include 的结果?可能会有所不同,具体取决于它是
a == b还是b == a,如果这些对象中只有一个对象覆盖了该方法。我建议你做my_arrays_of_objs.map(&:email).include? obj.email之类的事情。以与预期行为截然不同的方式覆盖方法将非常不利于代码的可读性。
标签: ruby-on-rails ruby activerecord