如何填充我为has_and_belongs_to_many关联创建的连接表?

时间:2015-08-25 20:57:10

标签: ruby-on-rails

我有两个模型,Event和Vip,每个模型都与HABTM关系相关联。 我有一个events_vips表,其中包含vip_id和event_id

的列

我的新活动表格:

<%= form_for [@organization, @event] do |f| %>
    <p>
        <%= f.label :when %>
        <%= f.date_select :when %>
    </p>
    <p>
        <%= f.label :name %>
        <%= f.text_field :name %>
    </p>
    <p>
        <%= f.label :vip %>
        <%= f.select :vip_id, options_for_select(@organization.vips.all.map {|v| [v.name, v.id]}) %>
    </p>
    <p>
        <%= f.submit %>
    </p>
<% end %>

我的活动控制器:

    def new
        @organization = Organization.find(params[:organization_id])
        @event = @organization.events.new
    end

    def create
        @organization = Organization.find(params[:organization_id])
        @event = @organization.events.build(event_params)

        if @event.save
            redirect_to organization_path(@organization)
        else
            render 'new'
        end
    end

我希望在创建事件时,我的events_vips表会填充新的事件/ vip关系。或者这是错误的做法吗?

修改

我的模特看起来像:

class Vip < ActiveRecord::Base
    belongs_to :organization
    has_and_belongs_to_many :events
end

class Event < ActiveRecord::Base
  belongs_to :organization
  has_and_belongs_to_many :vips
end

2 个答案:

答案 0 :(得分:0)

我会使用has_many :events, :through => :some_table_namehas_many :organizations, :through => :some_table_name而不是habtm。这样做的原因是,随着这种习惯,你在几个方面受到限制。首先,由于habtm构造的字母性质,连接表名称被限制为events_organizations,并且使用has_many:通过您可以使用可以更具描述性的任意表名称。

更重要的是,您无法在habtm连接表中存储有关该关系的任何其他信息。例如,在has_many:through中,您可以存储表编号,到达时间,停靠计划或适用于特定组织的其他信息,用于特定事件在连接表中,它属于。这样,连接表不仅存储关系,还存储有关该关系性质的信息。

在任何一种情况下,您的问题的答案都是在模型中使用accepts_nested_attributes_for :your_join_table_model,您将操纵数据(可能是两者)。

Here is part 1 of a railscast dedicated to the subject.

Here is a link to the HABTM checkboxes railscast, if you wanted to go that route.

答案 1 :(得分:0)

您需要找到params中的vip,然后找到event#vips

def create
    @organization = Organization.find(params[:organization_id])
    @event = @organization.events.build(event_params)

    if @event.save
        vip = Vip.find(event_params[:vip_id])
        @event.vips << vip # this will create the association
        redirect_to organization_path(@organization)
    else
        render 'new'
    end
end

现在添加验证检查总是一个好主意,例如确保vip param出现在表单中,但上面是如何实际伪造关联。保存事件后,可以进行vip关联。