红宝石在轨道上覆盖等于

时间:2011-01-17 09:58:19

标签: ruby-on-rails ruby

我有一个模型user.rb(它是一个ActiveRecord :: Base,不确定它是否与讨论相关)

在某些视图中,我通过以下方式比较两个用户:

<% if current_user == user %>

结果是不确定的(有时结果是真的,有时它是假的),我不知道为什么。

如果我将其切换到

<% if current_user.id == user.id %>

它按预期工作。但是我需要处理用户可以为空的情况。

我的问题是,这里发生了什么?

为什么user1 == user2在这里失败?

我应该覆盖==,还是

我应该使用替代方法,例如equal?,===或eql?

user.rb是ActiveRecord :: Base的意思是不应该默认比较id字段?

3 个答案:

答案 0 :(得分:3)

如果查看==

的源代码
      # File lib/active_record/base.rb, line 2427
2427:       def ==(comparison_object)
2428:         comparison_object.equal?(self) ||
2429:           (comparison_object.instance_of?(self.class) &&
2430:             comparison_object.id == id &&
2431:             !comparison_object.new_record?)
2432:       end

当对象id匹配时,您可以看到它应该返回true。如果您的代码<% if current_user == user %>对于同一个用户对象失败,那么您肯定会遇到奇怪的事情。

您可以在上下文中发布该代码段吗?

答案 1 :(得分:1)

来自http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-%3D%3D

  

如果是comparison_object,则返回true   相同的确切对象,或   comparison_object属于同一类型   和自己有一个ID,它等于   comparison_object.id。

     

请注意,新记录不同   根据定义,从任何其他记录,   除非另一个记录是   接收器本身。此外,如果你取   选择和离开的现有记录   身份证,你自己,这个   谓词将返回false。

     

还要注意销毁记录   在模型中保留其ID   实例,所以删除的模型仍然是   可比性。

它应匹配current_user == user

你如何获取current_user对象?

答案 2 :(得分:1)

如果你想进一步了解ruby中的平等,请看看这篇非常好的博客文章:

http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/

希望这有助于您理解。