问题
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
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:

Campaign creation 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
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} %>
and
<%= f.collection_select :metro_ids, Metro.all, :id, :full_name, {}, {multiple: true} %>
campaigns_params:
def campaign_params
params.require(:campaign).permit(:name, :campaign_category_metro_bid_id,
:metro_ids => [], :category_ids => [])
end
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:

回答1:
I think the problem may be the multi select that you have on categories and metros. You're essentially trying to fit multiple foreign_keys for the same reference into a single row record. If category ID and metro ID are both defined as integers, you would need to create multiple records in order to be able to save this.
You would need to add some logic to see if your selection params have a length of > 1 and based on that you'll need to create and save a new row. The logic would look something like this
params[:category_ids].each do |category|
params[:metro_ids].each do |metro|
@user.campaign.create(category_id: category, metro_id:metro) #any other params would go here too
end
end
This would essentially loop through your multi-select to create a new record for each combination.
来源:https://stackoverflow.com/questions/26028291/data-modeling-3-way-table-has-many-association