Rails的ActiveRecord的:三表的has_many通过:协会
我试图建立一个表来处理的位置和一定的运动已被设置为与下面的模型协会类别:
I am attempting to build a table to handle both the location and category a certain campaign has been set to with the following model associations:
class Campaign < ActiveRecord::Base
has_many :campaign_category_metro_bids, dependent: :destroy
has_many :metros, through: :campaign_category_metro_bids
has_many :categories, through: :campaign_category_metro_bids
end
class Metro < ActiveRecord::Base
has_many :campaign_category_metro_bids
has_many :campaigns, through: :campaign_category_metro_bids
has_many :categories, through: :campaign_category_metro_bids
end
class Category < ActiveRecord::Base
has_many :campaign_category_metro_bids
has_many :campaigns, through: :campaign_category_metro_bids
has_many :metros, through: :campaign_category_metro_bids
end
class CampaignCategoryMetroBid < ActiveRecord::Base
belongs_to :campaign
belongs_to :category
belongs_to :metro
end
在试图创建一个竞选选择两个不同的城市和类别的结果是空的paramters之一作为ID:
When attempting to create a campaign for selecting two different cities and categories the result is NULL for the id of one of the paramters as:
广告制作code:
def new
if signed_in?
# create new campaign
@user = User.find(params[:id])
@campaign = @user.campaigns.new
else
redirect_to signin_path
end
end
def create
@campaign = User.find(params["campaign"]["user_id"]).campaigns.build(campaign_params)
if @campaign.save
flash[:success] = "Campaign created!"
redirect_to current_user
else
render 'new'
end
end
更新时间: 创建活动的视图使用两个单独的collection_select类别和地铁为:
UPDATED The view to create the campaign uses two separate collection_select for Category and Metro as:
<%= f.collection_select :category_ids, Category.all, :id, :display_category, {}, {multiple: true} %>
和
<%= f.collection_select :metro_ids, Metro.all, :id, :full_name, {}, {multiple: true} %>
campaigns_params:
campaigns_params:
def campaign_params
params.require(:campaign).permit(:name, :campaign_category_metro_bid_id,
:metro_ids => [], :category_ids => [])
end
有没有更好的方式来允许创建一个3台关系,因为我尝试?
还是有办法来链接类别
和新城
车型的选择,这样所产生的表像之下在广告制作
Is there a better way to allow for the creation of a 3 table relation as I am attempting?
or a way to link the Category
and Metro
models at selection so that the resultant table is something like below upon campaign creation:
如果你想确保跨多个表我会首先验证数据的一致性。例如:
If you want to ensure data consistency across multiple tables I would begin with validations. For example:
class CampaignCategoryMetroBid < ActiveRecord::Base
belongs_to :campaign
belongs_to :category
belongs_to :metro
validates :campaign, presence: true
validates :category, presence: true
validates :metro, presence: true
end
您可能还希望这个约束添加到您的数据库,如果这就是你所需要的(见迁移指南)。这样,任何人都无法打破的一致性,甚至没有从DB CLI。现在,每一个你code尝试创建无外键一个CampaignCategoryMetroBid实例时,ActiveRecord的会喊和限制您的code,其余为行为。
You also might want to add this constraint to your db if that's what you need (see the migration guides). That way nobody will be able break the consistency, not even from the db cli. Now every time your code attempts to create a CampaignCategoryMetroBid instance without the foreign keys, ActiveRecord will shout and that constraints the rest of your code to "behave".
如果你真的只是想(或以其他方式调整表单数据)注入一些默认的外键,你可以做到这一点,而preprocessing表单数据在控制器的行动。例如:
If you really just want to inject some default foreign key (or otherwise tweak the form data) you can do this while preprocessing the form data in your controller actions. For example:
class CampaignsController < ActionController::Base
def create
# Possibly refactor to a before_action
if params[:campaign] && params[:capmaign][:metro_ids] && params[:capmaign][:metro_ids].empty?
params[:campaign][:metro_ids] = [DEFAULT_CAMPAIGN_ID]
end
# Do the rest
end
end
我希望这有助于为一般设置方向: - )
I hope this helps to generally set the direction :-)