Rails 在 Collection 中查找所有嵌套相册或 Collection
Rails Find all nested Albums or Collections in a Collection
这是我的两个模型:
Collection:
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
我需要一种方法来找到 parent Collection.
内的所有专辑 and/or Collection
关于如何完成此操作有什么想法吗?
这将允许我访问 parent Collection 等
中所有照片的列表
access a list of all the photos within a parent Collection
第一种方法,递归调用 get_photos 从 parent Collection 到它的 children 然后它的 grand-children 等等......直到有没有更多 child Collection.
class Collection < ActiveRecord::Base
# ...
def get_photos
albums.map(&:photos).flatten.tap |photos|
photos << children.map(&:get_photos).flatten
end
end
end
这可能会调用很多查询。
第二种方法,迁移 Collection table 以添加 collection path
列,因此如果 parent Collection c1
id 是1,它的路径是/1
,它的children,比如,c2
(id:2)和c3
(id:3)那么c2的路径是/1/2
和 c3 路径是 /1/3
,依此类推...每次在 parent Collection 下创建 child Collection 时,您设置它的路径#{parent_path}/#{id}
.
现在您可以使用查询 where('path LIKE ?', "#{parent_path}/%")
来获取 parent Collection.
的所有 children collections
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
如果您只想调用一个查询,您可以直接将 collection-path 添加到照片 table。
根据书SQL Anti-pattern,你的问题是Naive Trees
(Always Depend on One's Parent)。第二种方法是它的一种解决方案 - Path Enumeration
,其他方法是 Nested Sets
和 Closure Table
.
这是我的两个模型:
Collection:
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
我需要一种方法来找到 parent Collection.
内的所有专辑 and/or Collection关于如何完成此操作有什么想法吗?
这将允许我访问 parent Collection 等
中所有照片的列表access a list of all the photos within a parent Collection
第一种方法,递归调用 get_photos 从 parent Collection 到它的 children 然后它的 grand-children 等等......直到有没有更多 child Collection.
class Collection < ActiveRecord::Base
# ...
def get_photos
albums.map(&:photos).flatten.tap |photos|
photos << children.map(&:get_photos).flatten
end
end
end
这可能会调用很多查询。
第二种方法,迁移 Collection table 以添加 collection path
列,因此如果 parent Collection c1
id 是1,它的路径是/1
,它的children,比如,c2
(id:2)和c3
(id:3)那么c2的路径是/1/2
和 c3 路径是 /1/3
,依此类推...每次在 parent Collection 下创建 child Collection 时,您设置它的路径#{parent_path}/#{id}
.
现在您可以使用查询 where('path LIKE ?', "#{parent_path}/%")
来获取 parent Collection.
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
如果您只想调用一个查询,您可以直接将 collection-path 添加到照片 table。
根据书SQL Anti-pattern,你的问题是Naive Trees
(Always Depend on One's Parent)。第二种方法是它的一种解决方案 - Path Enumeration
,其他方法是 Nested Sets
和 Closure Table
.