Ruby on rails 为什么ActiveRecord不够聪明,不知道父对象的object_id应该等于其子对象的父对象的object_id?

Ruby on rails 为什么ActiveRecord不够聪明,不知道父对象的object_id应该等于其子对象的父对象的object_id?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我本以为这里的结果都是真实的 相反,它们都是false 为什么ActiveRecord会以这种方式工作,而不是识别这些是相同的Ruby对象?对象ID是指向对象的指针(某种程度上)。rails对象的加载不会“共享”内存空间,因此在执行child.parent时,您将获得父对象的副本。要理解这一点,您可以执行parent.something=foo,然后比较child.parent.something,您会发现它们是不同的。您必须从数据库重新加载子对象,然后它才能反映对父对象的更改 但是,很可能您使

我本以为这里的结果都是真实的

相反,它们都是
false

为什么ActiveRecord会以这种方式工作,而不是识别这些是相同的Ruby对象?

对象ID是指向对象的指针(某种程度上)。rails对象的加载不会“共享”内存空间,因此在执行child.parent时,您将获得父对象的副本。要理解这一点,您可以执行parent.something=foo,然后比较child.parent.something,您会发现它们是不同的。您必须从数据库重新加载子对象,然后它才能反映对父对象的更改


但是,很可能您使用了错误的ID值。如果希望使用ActiveRecord ID(例如SQL DBMS中ID列的值),请尽可能使用@father.ID==child.parent.ID来返回现有对象,而不是创建新对象。ActiveRecord必须跟踪创建了哪些对象以及它们响应的数据库中的哪个条目,这会带来一些开销。即使这样,它仍然必须在数据库中查找child.parent,才能知道它是@father所代表的同一个条目,因此从这个缓存中不会有任何显著的性能提升(在ruby方面,它可以安全地分配多个对象,但代价是簿记开销,但在数据库方面,它应该基本相同)


因此,考虑到AR人员可能认为阻止与同一数据库条目对应的不同对象是有害的,或者至少是不值得的,所以他们选择不这样做。

重用对象是有问题的。如果您对模型实例进行更改,但在保存它之前,您会再次发现bri是否返回同一对象?新对象应反映数据库,但旧对象仍应包含更改的数据


因此,是的,跟踪每个实例和每个实例中的脏字段会带来很大的开销。节省的内存不值得这么做。

就我而言,AR至少应该支持一个身份映射插件。这是我在使用AR时处理的最大问题。我意识到这会增加一些开销,但寿命很短内存开销比让数据库一次又一次地提取相同的记录而对数据库征收不适当的税要好。这就像GC。你可以自己做,也可以使用高级语言将其抽象出来,以便专注于业务逻辑。你可以大惊小怪地优化AR,也可以利用身份映射。

如果有人今年在被问到这个问题后偶然发现了它(像我一样!),请查看


它建议使用
:inverse\u of
来建立双向关联。我希望我过去没有这么多次浏览过这一部分文档!

我在这里故意查看Ruby“object\u id”而不是AR“id”属性。我的问题真的与AR为什么以这种方式工作有关。我想你明白我想要的了r但我不完全理解你的解释。你似乎在说,为了识别它们是同一个Ruby对象,AR必须保留一个哈希表并进行查找。也许吧。但我认为这不一定会涉及额外的开销,因为AR必须缓存其结果,以防你第二次请求它们。不是吗让我们用一个身份图来实现这个目的吧?用find(…)来代替是不是有意义返回内存中的对象,如果它尚未加载到内存中,则返回数据库?这也是我的一个问题。如果我在像您这样的关联中更新对象的属性,我现在有两个对象不同步。在我看来,这是不一致和混乱的。
  @father = Hierarchy.find(:first, :conditions => ['label = ?', 'father'])

  @father.children.each do |child|
    puts @father.object_id == child.parent.object_id
  end