Rails 多级 has_man 通过
Posted
技术标签:
【中文标题】Rails 多级 has_man 通过【英文标题】:Rails Multi Level has_many through 【发布时间】:2014-09-26 00:29:07 【问题描述】:我正在尝试构建多层次模型,如图所示。当用户创建活动时,他们将从表 Category 和 Metro 中选择一些类别和一些 Metro。然后,这些选择将被放置在两个表中,分别是 campaign_category 和campaign_metro。但是在创建这些条目后,我希望在另一个表中填充表campaign_category_metro 中这些组合的排列,以允许链接活动、为用户选择的类别和都市圈以设置出价。
更新:
例如,假设用户创建了一个 ID 为 10 的活动,并选择了 ID 为 1 和 2 的类别,以及 ID 为 3 和 4 的 Metros。在表格中会出现 Campaign_category:
并在表中显示campaign_metro:
在 campagin_category_metro 中,我希望将上表中的那些置换行设为:
然后用户可以对这些广告系列/地铁组合设置出价。
截至目前,在创建广告系列并选择类别和都市圈时,我可以填充表格campaign_category 和campaign_metro,但最终表格campaign_category_metro 仍为空白。以下是我的模型:
第一级:
class Campaign < ActiveRecord::Base
has_many :campaign_metros, dependent: :destroy
has_many :metros, through: :campaign_metros
has_many :campaign_categories, dependent: :destroy
has_many :categories, through: :campaign_categories
end
class Category < ActiveRecord::Base
has_many :campaign_categories, dependent: :destroy
has_many :campaigns, through: :campaign_categories
end
class Metro < ActiveRecord::Base
has_many :campaign_metros, dependent: :destroy
has_many :campaigns, through: :campaign_metros
end
二级(填充,但与campaign_category_metro 的关系不执行任何操作):
class CampaignCategory < ActiveRecord::Base
belongs_to :campaign
belongs_to :category
has_many :campaign_category_metros, dependent: :destroy
has_many :campaign_metros, through: :campaign_category_metros
end
class CampaignMetro < ActiveRecord::Base
belongs_to :campaign
belongs_to :metro
has_many :campaign_category_metros, dependent: :destroy
has_many :campaign_categories, through: :campaign_category_metros
end
第三级(创建活动时没有任何显示):
class CampaignCategoryMetro < ActiveRecord::Base
belongs_to :campaign_category
belongs_to :campaign_metro
end
如何允许在创建广告系列时使用所选类别和都市圈的总排列填充第三级表?
【问题讨论】:
您想用 CampaignCategoryMetro 解决什么问题?即使填充,其中的信息也是多余的。 是的,为什么你加入模型需要记录才能知道其他模型是什么?你可以问它的父母。 我更新了表格campaign_category_metro 来说明原因。类别和地铁的每个选择,这些分组的组合将有自己的用户稍后设置的各自的投标价格 @diego.greyrobot 是否可以添加任何内容,以便在创建活动并选择类别和都市时填充表campaign_category_metro? campaign_category_metro 表的用途是什么?你的问题不清楚。我对您的架构感到困惑。您是否正在尝试获取已为创建的每个广告系列选择的对 Metro 和类别的组合? 【参考方案1】:以下代码将生成您在示例中发布的campaign_category_metro 表:
campaign = Campaign.create # pretend the id is now 10
# this will create the join tables you provided as examples
campaign.categories << [Category.find(1), Category.find(2)]
campaign.metros << [Metro.find(3), Metro.find(4)]
# Get the join tables
campaign_categories = campaign.campaign_categories
campaign_metros = campaign.campaign_metros
我们现在有这些:
到目前为止一切顺利,只需设置一些上下文以确保我们在同一页面上。现在生成最终排列并创建最后一个表:
@campaign_category_metros = []
# this outer loop will run twice and provide campaign_category ids 15 and 16
campaign_categories.each do |campaign_category|
# this inner loop will run twice and provide campaign_metro ids 25 and 26
campaign_metros.each do |campaign_metro|
# this next bit will run 4 times and pair 15 with 25 and 26 and 16 with 25 and 26
@campaign_category_metros << CampaignCategoryMetro.create(
campaign_category_id: campaign_category.id,
campaign_metro_id: campaign_metro.id
)
end
end
现在@campaign_category_metros
将等于:
当然,除了空白投标。您可以在列表中呈现@campaign_category_metros
,以允许用户对这 4 种组合进行出价。
这里的想法是,我们将为每个campaign_category
创建一个campaign_category_metro
记录和每个campaign_metro
。
注意:Rails 中没有内置机制可以为您执行此操作。
【讨论】:
谢谢。注意:我使用活动记录来创建campaign_category 和campaign_metro。但是对于您的实施,如果我们只是按照您的概述对记录的创建进行硬编码,那么campaign_category_metro 表的可更新性如何。还是我还需要构建单独的更新/编辑方法,只注意模型的变化? 您可以将该代码放入或从活动控制器中调用它 create actin 因为您想在制作新活动时创建新排列。然后在campaign_category_metros 控制器中,您可以直接更新这些最终记录。 另请注意,我在创建campaign.categories
和campaign.metros
的位置编写的第一个代码 sn-p 只是一个示例,它代表了您在视图中为让用户创建活动所做的操作并选择类别和都市圈。不要使用该部分,仅使用您使用当前创建的广告系列的都市圈和类别来创建决赛桌的部分。
好的,如果我还编辑/更新了营销活动的地铁和类别的原始选择,例如我将不再使用类别 15 或 16,并切换到类别 82 和 12,如何然后我可以删除 Campaign_Category_Metro 中的其他行吗?
在这种情况下,我会在campaign_category_metros
表中添加一个campaign_id
字段,以跟踪哪个广告系列创建了这些排列,当您删除一个广告系列时,只需调用CampaignCategoryMetro.where(campaign_id: @campaign_id).delete_all
。确保在我提供的嵌套循环代码中创建排列时添加campaign_id。以上是关于Rails 多级 has_man 通过的主要内容,如果未能解决你的问题,请参考以下文章
通过while循环或Reduce,仅基于R的多级员工经理关系
通过Dapr实现一个简单的基于.net的微服务电商系统(十八)——服务保护之多级缓存...