【问题标题】:Rails Find all nested Albums or Collections in a CollectionRails 查找集合中所有嵌套的专辑或集合
【发布时间】:2022-01-26 01:15:26
【问题描述】:

这是我的两个模型:

收藏:

class Collection < ActiveRecord::Base

  has_many :children, class_name: "Collection", foreign_key: "parent_id"
  belongs_to :parent, class_name: "Collection", foreign_key: "parent_id", optional: true
  has_many :albums, dependent: :nullify

end

专辑:

class Album < ActiveRecord::Base

  belongs_to :collection, optional: true
  has_many :photos, dependent: :destroy

end

我需要一种方法来查找父收藏夹中的所有专辑和/或收藏夹。

关于如何实现这一点的任何想法?

这将允许我访问父集合等中所有照片的列表。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    access a list of all the photos within a parent Collection

    第一种方法,从父集合递归调用 get_photos 到它的子集合,然后是它的孙子等等......直到没有更多的子集合。

    class Collection < ActiveRecord::Base
     # ...
     def get_photos
       albums.map(&:photos).flatten.tap |photos|
         photos << children.map(&:get_photos).flatten
       end
     end
    end
    

    这可能会调用很多查询。

    第二种方法,迁移Collection表添加collection path列,所以如果父Collectionc1id为1,则其路径为/1,其子Collection例如c2(id: 2 ) 和c3(id: 3) 那么c2路径是/1/2和c3路径是/1/3,以此类推...每次在父Collection下创建子Collection时,设置它的路径#{parent_path}/#{id} .

    现在您可以使用查询where('path LIKE ?', "#{parent_path}/%") 来获取父集合的所有子集合。

    class Collection < ActiveRecord::Base
     # ...
     def get_photos
       collection_ids = where('path LIKE ?', "#{self.path}/%").pluck(&:id)
       album_ids = Album.where(collection_id: collection_ids).pluck(&:id)
       Photo.where(album_id: album_ids).all
     end
    end
    

    如果您只想调用一个查询,可以直接将集合路径添加到 Photo 表中。

    根据SQL Anti-pattern 这本书,你的问题是Naive Trees(总是依赖于一个人的父母)。第二种方法是一种解决方案 - Path Enumeration,其他是 Nested Sets 和 Closure Table。

    【讨论】:

    • 这是一个绝妙的答案。我一定会研究那个解决方案。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多