2014-09-23 73 views
0

我試圖建立一個表來處理雙方的位置和類別一定的活動已被設置爲以下模型協會:Rails的ActiveRecord的:三表的has_many通過:協會

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:

enter image description here

建立廣告活動代號:

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類別和地鐵爲:

 <%= 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:

def campaign_params 
     params.require(:campaign).permit(:name, :campaign_category_metro_bid_id, 
             :metro_ids => [], :category_ids => []) 
    end 

有沒有更好的方法來允許我嘗試創建3表關係? 還是有辦法使得所得表類似下面根據活動創建CategoryMetro機型在選擇鏈接:

enter image description here

+0

你可以從你的控制器中添加廣告系列創建代碼的方向? – Eric 2014-09-23 01:23:41

+0

@Eric你需要其他信息嗎? – Sauron 2014-09-23 01:40:33

+1

是的,你的campaign_params方法:) – Eric 2014-09-23 05:06:32

回答

-1

如果你想確保跨多個表我會驗證開始數據的一致性。例如:

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 

你也可能要將此約束添加到您的數據庫,如果這就是你所需要的(見遷移指南)。這樣一來,沒有人會破壞一致性,甚至不會從數據庫cli中獲取。現在,每當您的代碼嘗試創建沒有外鍵的CampaignCategoryMetroBid實例時,ActiveRecord都會大聲喊叫,並將您的其他代碼限制爲「行爲」。

如果你真的只想注入一些默認的外鍵(或者調整表單數據),你可以在預處理控制器動作中的表單數據的時候這樣做。例如:

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 

我希望這有助於通常設置:-)

+0

這是否有助於防止出現在這裏的情況:http://i.stack.imgur.com/u4TyA.png我想要選擇在行中的「Metros」和「Category」的排列,而不是可以在圖像中看到NULL值。對於id爲9,10的'category_id'下的行,它應該被列爲'1'和'2',而不是NULL – Sauron 2014-09-23 12:49:06

+0

我不希望有任何默認外鍵,但允許按照我的演示進行選擇。我需要的補充是什麼? – Sauron 2014-09-24 02:18:48

+0

是的,首先,驗證良好將確保這種情況不會再發生,無論您的代碼庫的其他部分如何。這會給你一致。 – Renra 2014-09-24 09:24:50