gpt4 book ai didi

ruby-on-rails - 在 Rails 中查找自引用关系中的后代

转载 作者:太空宇宙 更新时间:2023-11-03 16:46:32 30 4
gpt4 key购买 nike

我有一个 Image 模型,它有 has_many 个版本。版本也是图像,设置为自引用关系。

class Image < ActiveRecord::Base
belongs_to :parent, class_name: 'Image'
has_many :versions, class_name: 'Image', foreign_key: :parent_id
end

创建新图像时,回调会在数据库中搜索具有相同名称的图像。如果它找到一个,它会将其 parent_id 设置为新图像的 id。这将创建一个树,结构:

| id | name  | parent_id |
--------------------------
| 1 | a.gif | 2 |
| 2 | a.gif | 3 |
| 3 | a.gif | NULL |
--------------------------

是否有一种简单的方法来检索图像的所有后代? image.versions 按预期找到 ID 为 2 的图像。要获取 ID 为 1 的图像,我必须遍历图像 2。

image = Image.find(3)
versions = image.versions # this finds image 2
descendents = versions.each { |v| v.versions } # etc...

我尝试使用 has_one 关系:

  belongs_to :parent, class_name: 'Image'
has_one :version, class_name: 'Image', foreign_key: :parent_id
has_many :versions, through: :version

那仍然只检索 id 为 2 的图像,而不是整个后裔树。我有两个已知的选择:

  1. 使用回调来更新所有具有相同名称的图像,但我不想使用更复杂的回调。
  2. 使用单独的表来存储版本。但由于两个原因,这很复杂。
    1. 因为我跟踪 Image 上的所有事件,所以通过将 Image 转换为 ImageVersion,它的引用将在 Activity 表中丢失(它的类和 ID 会发生变化)。
    2. 人们一次创建多个新图像(他们不会一个接一个地更新),只有在它们被插入后我才能进行版本控制,这是一个昂贵的过程。这意味着默认情况下将创建新图像。由于上传的机制,将它们转换为版本并更新原始版本被证明是非常麻烦的。

最佳答案

我完全同意您应该将 ImageVersion 移动到新模型而不是创建这棵树。

这会简化事情,并且(在我看来)这将是一种更好的方法。

但如果您真的需要这样做,您应该检查这个 gem,我从未使用过它,但它似乎正是您所要求的:https://github.com/take-five/activerecord-hierarchical_query

希望对您有所帮助。

关于ruby-on-rails - 在 Rails 中查找自引用关系中的后代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31749198/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com