Rails ActiveRecord 模型链表

6

通过大量的谷歌搜索,我现在要提出一个似乎并不经常发生但仍然非常基本的问题。Active Record中的链表。就我目前的了解,我们需要在模型中有两个关联:

class Child < ActiveRecord::Base
  belongs_to :parent
  belongs_to :next, :class_name => 'Child', :foreign_key => 'next_id'
  belongs_to :previous, :class_name => 'Child', :foreign_key => 'previous_id'
end

现在我们可以获取父元素的所有子元素:

children = Child.where("parent_id = ?", parent_id)

现在来回答这个问题:我当然希望通过一个查询从数据库中获取所有子元素,但是我还想按照链接顺序遍历子元素,这意味着第一个子元素将是具有先前属性为nil的子元素,下一个子元素将是由第一个子元素的下一个属性连接的子元素,以此类推,直到下一个属性为nil。 是否可以这样做,还是我需要查询第一个子元素,然后逐个访问子元素而不进行“预缓存”?
2个回答

3

Resortranked-model宝石是其他替代品。 第一个使用类似于链表的方法。第二个使用位置属性。


最终我们决定使用ranked-model。 - Daniel Richter

1

你应该使用Rails acts_as_list gem。它会存储列表中项目的位置,甚至可以为列表和belongs_to设置父对象的范围。通过允许您查询所有元素,然后正确排序,它也可以解决此问题。


1
我也曾经想过这个问题,但是acts_as_list并没有给你链表的主要好处——在任意位置进行廉价插入和删除。 - Chowlett
很高兴知道 gem acts_as_list (因为直到现在,我一直自己实现)。但确切地说,这就是我想要摆脱的...如果删除一个对象,我只想更改之前和下一个模型的属性,而不是浏览数百行更改位置属性。 - Daniel Richter
1
你可以重写 destroy 方法,使其更新它的邻居属性。 - Draiken
@Draiken 好的,问题仍然是,是否可以从一个父级获取所有子级,然后以链表方式迭代它们... - Daniel Richter
acts_as_list存在一些问题,在README中没有提到:http://rhnh.net/2010/06/30/acts-as-list-will-break-in-production - Chris Aitchison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接