有没有办法轻松有效地获取父模型的相应(子)模型,然后在模板中呈现它?我想知道如何使用和不使用连接
例如,请考虑以下3个表:
# ProductGroup is the highest parent
class ProductGroup < ActiveRecord::Base
attr_accessible :name, :merchant_id
has_many :product_items
has_many :product_group_selections
end
# ProductItem is a child of ProductGroup
class ProductItem < ActiveRecord::Base
attr_accessible :base_price, :name, :product_group_id
belongs_to :product_group
end
# ProductGroupSelection is a child of ProductGroup
class ProductGroupSelection < ActiveRecord::Base
attr_accessible :name, :price_extra, :product_attr_group_id, :product_item_id
belongs_to :product_group
has_many :product_group_selection_attrs
end
# ProductGroupSelectionAttr is a child of ProductGroupSelection
class ProductGroupSelectionAttr < ActiveRecord::Base
attr_accessible :name, :product_group_id
belongs_to :product_group_selection
end
我想要的是一个看起来像这样的数据结构(当搜索product_groups for merchant_id = 1时)
merchant_id 1 => {
ProductGroup.name, ProductGroup.merchant_id,
ProductItems => [...],
ProductGroupSelections => {ProductGroupSelections.name, ProductGroupSelectionAttrs => [...]}
}
通过这种方式,我可以循环遍历所有组及其子模型,以使用ERB生成表单。
谢谢
答案 0 :(得分:2)
当迭代一组记录时,这些记录又会产生集合,你将遇到臭名昭着的N + 1查询。基本上对于每个ProductGroup,您将运行查询以撤回其所有ProductItem记录。如果你处理两级关系,那就更糟了。
为了更有效地完成这项工作,您希望利用ActiveRecord定义的包含作为在尽可能少的查询中急切加载关联的方法。
ProductGroup.includes(:product_items).includes(:product_group_selections => :product_group_selection_attrs)
从那里你只需添加你需要的任何条件,为ProductGroup加载的任何条件都将确保所有相关模型也被加载。
现在,您只需正常迭代您的关联。假设@product_groups有一个ProductGroup
的集合@product_groups.each do |product_group|
# do stuff with product_group
product_group.product_items.each do |product_item|
# do stuff with product_item
end
product_group.product_group_selections do |product_group_selection|
# do stuff with product_group_selection
product_group_selection.product_group_selection_attrs do |product_group_selection_attr|
# do stuff with product_group_selection_attr
end
end
end
rails设置关联的默认方式应该满足您要求的数据结构,只需要实际记录而不是散列哈希值,无论如何都需要加载以创建哈希哈希值。
答案 1 :(得分:0)
也许是这样的:
class ProductGroup < ActiveRecord::Base
# I have no idea what to call this method
def merchant_data
{:name => self.name, :merchant_id => self.merchant_id, :items => self.product_items, :selections => self.product_group_selections}
end
end
你的控制器里面你会有这样的东西:
def merchant_search
@product_group = ProductGroup.find_by_merchant_id(params[:merchant_id})
@merchant_data = @product_group.merchant_data
#@merchant_data => {:name=>"...", :merchant_id=> 1, :items=>[....], :selections=>[..]}
end
只需在视图中使用哈希,类似于如何使用任何其他实例变量,只有这次使用哈希。例如,如果您想循环遍历返回的数据结构中的所有项目:
@merchant_data[:items].each {|item| ... }