Rails的ActiveRecord的:三表的has_many通过:协会 [英] Rails ActiveRecord: Three Table has_many through: associations

查看:223
本文介绍了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 C​​LI。现在,每一个你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 :-)

这篇关于Rails的ActiveRecord的:三表的has_many通过:协会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆