通过递归 has_many 关系创建 has_many 关系
Creating an has_many relationship through a recursive has_many relation
情况:
class Company < ActiveRecord::Base
has_many :groups #<-- recursive sub-groups
has_many :profiles, through: :groups #<-- This only returns the :profiles of the first groups layer
end
class Group < ActiveRecord::Base
belongs_to :company, optional: true
belongs_to :group, optional: true
validate :company_xor_group
has_many :groups
has_many :profiles
end
class Profile < ActiveRecord::Base
belongs_to :group
end
示例数据:
company = Company.new
group = Group.new.profiles.build(name: 'A')
sub_group = Group.new.profiles.build([{name: 'B'},{name: 'C'}])
group.groups << sub_group
company.groups << group
所以一家公司有一个组,其中包含一个配置文件和一个子组,其中包含 2 个配置文件。
所以我想获取一家公司的所有资料。当前,has_many :profiles, through: :groups
关系,只有 returns 第一个子组的配置文件:
company.profiles.length # 1
我正在寻找返回 ActiveRecord AssociationProxy 的解决方案。我尝试了以下方法:
# Company Model
def all_profiles
groups.map(&:all_profiles)
end
# Group Model
def all_profiles
profiles + groups.map(&:all_profiles)
end
但是这个 returns 是一个数组,而不是 AssociationProxy
。
正如@spickermann 的回应,递归表的巨大帮助是 Awesome Nested Set。
@arieljuod 给出了我的问题“如何将其发送到 return ActiveRecord AssociationProxy?”的答案:
# Company Model
def all_profiles
Profile.where(group_id: groups.map(&:all_groups).flatten.map(&:id))
end
# Group Model
def all_groups
[self].push(groups.map(&:all_groups)).flatten.compact
end
在我的解决方案中,这仍然非常有效,因为递归组是预加载的。因此 all_groups
方法不会触发任何新查询。
情况:
class Company < ActiveRecord::Base
has_many :groups #<-- recursive sub-groups
has_many :profiles, through: :groups #<-- This only returns the :profiles of the first groups layer
end
class Group < ActiveRecord::Base
belongs_to :company, optional: true
belongs_to :group, optional: true
validate :company_xor_group
has_many :groups
has_many :profiles
end
class Profile < ActiveRecord::Base
belongs_to :group
end
示例数据:
company = Company.new
group = Group.new.profiles.build(name: 'A')
sub_group = Group.new.profiles.build([{name: 'B'},{name: 'C'}])
group.groups << sub_group
company.groups << group
所以一家公司有一个组,其中包含一个配置文件和一个子组,其中包含 2 个配置文件。
所以我想获取一家公司的所有资料。当前,has_many :profiles, through: :groups
关系,只有 returns 第一个子组的配置文件:
company.profiles.length # 1
我正在寻找返回 ActiveRecord AssociationProxy 的解决方案。我尝试了以下方法:
# Company Model
def all_profiles
groups.map(&:all_profiles)
end
# Group Model
def all_profiles
profiles + groups.map(&:all_profiles)
end
但是这个 returns 是一个数组,而不是 AssociationProxy
。
正如@spickermann 的回应,递归表的巨大帮助是 Awesome Nested Set。
@arieljuod 给出了我的问题“如何将其发送到 return ActiveRecord AssociationProxy?”的答案:
# Company Model
def all_profiles
Profile.where(group_id: groups.map(&:all_groups).flatten.map(&:id))
end
# Group Model
def all_groups
[self].push(groups.map(&:all_groups)).flatten.compact
end
在我的解决方案中,这仍然非常有效,因为递归组是预加载的。因此 all_groups
方法不会触发任何新查询。