2010-11-25 51 views
0

我有以下三種模式(滑軌2.3.8)與自己的屬性連接表使用accepts_nested_attributes_for - 重複行

class Outbreak < ActiveRecord::Base 
     has_many :incidents, :dependent => :destroy 
     has_many :locations, :through => :incidents 

     accepts_nested_attributes_for :incidents, :allow_destroy => true 
     accepts_nested_attributes_for :locations, :allow_destroy => true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } 

    end 

    class Incident < ActiveRecord::Base 
     belongs_to :outbreak 
     belongs_to :location 
    end 


    class Location < ActiveRecord::Base 
has_many :incidents 
has_many :outbreaks, :through => :incidents 

    accepts_nested_attributes_for :incidents, :allow_destroy => true 

    end 

從表格中的參數似乎是好

「outbreak」=> { 「locations_attributes」=> {「0」=> {「lon」=>「 - 1.39」,「placename」=>「wetwe」,「hpu_id」=>「15」 >>「」,「地址_2」=>「」,「地址_3」=>「」,「地址_id」=>「10」,「地址_1」=>「」,「城鎮」=> lat「=>」50.89「}},」incidents_attributes「=> {」0「=> {」subtype_id「=>」7「,」category_id「=>」1「,」detail「=>」「 ,「subcategory_id」=>「2」}} }

但是,當保存爆發時,在爆發和位置表的Incidents表(連接表)和單行中創建3行。

在事件表中的行沒有完全從PARAMS填充如下:

id outbreak_id location_id category_id subcategory_id subtype_id detail created_at updated_at 

57 23 NULL  1  2   7       2010-11-25 14:45:18.385905 2010-11-25 14:45:18.385905 
58 23 27   NULL  NULL  NULL NULL   2010-11-25 14:45:18.39828 2010-11-25 14:45:18.39828 
59 23 27   NULL   NULL  NULL  NULL   2010-11-25 14:45:18.403051 2010-11-25 14:45:18.403051 

這一定是由於參數的任何格式或多個accepts_nested_attributes_for方法 - 我怎麼剛纔在Incidents表中輸入一行所有參數信息?

回答

2

第二次本週迄今我已經回答了我的問題^^那會教我把更多的精力在放棄並張貼在網絡上尋求幫助之前,

看着我原來的後仍有的問題,我沒有足夠的信息來正確回答這個問題 - 這個問題(除了模型的建立)下降到在爆發控制器的新方法爆發構造,

原始Outbreaks_controller

def new 

    @outbreak = Outbreak.new 
    @outbreak.risks.build 
    //links locations directly to Outbreak instead of through Incidents 
    @outbreak.locations.build 
    @outbreak.incidents.build 

    respond_to do |format| 
     format.html # new.html.erb 
     format.xml { render :xml => @outbreak } 
    end 
end 

修正了breaks_controller

def new 

    @outbreak = Outbreak.new 
    @outbreak.risks.build 
    //builds Incidents then a Location through that incident 
    @outbreak.incidents.build.build_location 

    respond_to do |format| 
     format.html # new.html.erb 
     format.xml { render :xml => @outbreak } 
    end 
end 

更改到三款車型

class Outbreak < ActiveRecord::Base 
     has_many :incidents, :dependent => :destroy 
     has_many :locations, :through => :incidents 

     accepts_nested_attributes_for :incidents, :allow_destroy => true 


    end 

    class Incident < ActiveRecord::Base 
     belongs_to :outbreak 
     belongs_to :location 

     accepts_nested_attributes_for :location, :allow_destroy => true 
    end 


    class Location < ActiveRecord::Base 
     has_many :incidents 
     has_many :outbreaks, :through => :incidents 

    end 

這似乎是確定的工作 - 還貼出了創建行動和主要形式

+0

非常感謝這一點,因爲我與雙向映射struggeling有:通過,以及...但你可以發佈您的創建操作和如果可能的話,也可以使用表格(僅供參考)。 – tbk 2010-12-02 12:35:26

1

的創建操作只需要提供嵌套PARAMS:爆發(模型完成這項工作)。

def create 

    @outbreak = Outbreak.new(params[:outbreak]) 
    @outbreak.user_id = current_user.id 

     respond_to do |format| 
    if @outbreak.save 
     flash[:notice] = 'Outbreak was successfully created.' 
     format.html { redirect_to(@outbreak) } 
     format.xml { render :xml => @outbreak, :status => :created, :location => @outbreak } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @outbreak.errors, :status => :unprocessable_entity } 
     end 
    end 
end 

爆發的形式是很長,所以我一直把它刪減到所提到的兩個部分(雖然有可能是多個屬性和領域,這裏比是需要得到一個想法)。

嵌套字段的HTML元素ID示例可以在Javascript observe_field助手的底部找到。我對nested_attributes_for諧音的AJAX更新時發的帖子也可能是有用的AJAX update of accepts_nested_attributes_for

<% form_for(@outbreak, :html => {:multipart => true}) do |form| %> 
    <%= form.error_messages %> 
    <div id="tabs"> 
     <ul> 

      <li ><a href="#tabs_b">Outbreak</a></li> 
      <li ><a href="#tabs_c">Location</a></li> 

     </ul> 


      <div id="tabs_b"> 
       <fieldset id="b" class="form_div"> 
        <legend>Outbreak</legend> 

        <fieldset> 
         <legend>References</legend> 
         <div class="left_form"> 
         <%= form.label :user_reference %> 
         </div> 
         <div class="right_form"> 
         <%= form.text_field :user_reference %> 
         </div> 
         <div style="clear:both;"></div> 

        </fieldset> 

       </fieldset> 
      </div> 
      <div id="tabs_c"> 
       <fieldset id="c" class="form_div" > 

        <legend>Location</legend> 
         <div id="location_error"></div> 
          <fieldset> 
          <legend>Setting</legend> 
       <% form.fields_for :incidents do |incident_form| %> 

            <div class="left_form"> 
            <%= incident_form.label :category_id %> 
            </div> 

            <div class="right_form"> 
            <div id="incident_category_select"> 
            <%= render :partial => 'category_select', :locals => {:categories => @categories, :incident_form => incident_form} %> 
            </div> 
            </div> 
            <div style="clear:both;"></div> 

            <div class="left_form"> 
            <%= incident_form.label :subcategory_id %> 
            </div> 
            <div class="right_form"> 
            <div id="incident_subcategory_select"> 
            <%= render :partial => 'subcategory_select', :locals => { :subcategories => @subcategories, :incident_form => incident_form } %> 
            </div> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= incident_form.label :subtype_id %> 
            </div> 
            <div class="right_form"> 
            <div id="incident_subtype_select"> 
            <%= render :partial => 'subtype_select', :locals => { :subtypes => @subtypes, :incident_form => incident_form } %> 
            </div> 
            </div> 
            <div style="clear:both;"></div> 
            <div id="cuisine_div"> 
            <% if @outbreak.outbreak_type == "FOODBORNE" %> 
             <div class="left_form"> 
              <%= label :incident, :cuisine_id %> 
             </div> 
             <div class="right_form"> 
              <% cuisine_select = (@incident != nil ? @incident.cuisine_id.to_i : '') %> 
              <%= incident_form.select(:cuisine_id, "<option value='' >Please select</option>" + options_from_collection_for_select(@cuisines, :id, :name, cuisine_select)) %> 
             </div> 
            <% end %> 

            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= incident_form.label :detail %> 
            </div> 
            <div class="right_form"> 
            <%= incident_form.text_field :detail %> 
            </div> 


         </fieldset> 
         <fieldset> 
          <legend>Details</legend> 
          <% incident_form.fields_for :location do |location_form| %> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :placename %> 
            </div> 
            <div class="right_form"> 
            <%= location_form.text_field :placename %> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :address_1 %> 
            </div> 
            <div class="right_form"> 
            <%= location_form.text_field :address_1 %> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :address_2 %> 
            </div> 
            <div class="right_form"> 
            <%= location_form.text_field :address_2 %> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :address_3 %> 
            </div> 
            <div class="right_form"> 
            <%= location_form.text_field :address_3 %> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :town %> 
            </div> 
            <div class="right_form"> 
            <%= location_form.text_field :town %> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :postcode %> 
            </div> 
            <div class="right_form"> 
            <%= location_form.text_field :postcode %> 
            </div> 
            <div style="clear:both;"></div>   
            <div class="left_form"> 
            <%= location_form.label :region_id %> 
            </div> 
            <div class="right_form" > 
             <% region_select = (@location != nil ? @location.region_id.to_i : '') %> 
            <%= location_form.select(:region_id, "<option value=''>Select a region</option>" + options_from_collection_for_select(@regions, :id, :name, region_select)) %> 
            </div> 
            <div style="clear:both;"></div> 
            <div class="left_form"> 
            <%= location_form.label :hpu_id %> 
            </div> 
            <div class="right_form" > 
            <% hpu_select = (@location != nil ? @location.hpu_id.to_i : '') %> 
            <%= location_form.select(:hpu_id, "<option value=''>Select a HPU</option>" + options_from_collection_for_select(@hpus, :id, :name, hpu_select)) %> 
            </div> 
            <div style="clear:both;"></div> 

           <%= location_form.hidden_field :lon, :value => '' %> 
           <%= location_form.hidden_field :lat, :value => '' %> 
           <%= hidden_field_tag :postcode_error, :value => '0' %> 
           <% end %> 
          </fieldset> 


        <% end %>  

       </fieldset> 

      </div> 


    </div> 
    <% end %> 

    <div style="clear: both; margin: 10px;"></div> 
    <%= observe_field(:outbreak_incidents_attributes_0_location_attributes_postcode, 
       :url => { :controller => :locations, :action => :find_lonlat }, 
       :on => "onchange", 
       :loading => "Element.show('loader')", 
       :success => "Element.hide('loader')", 
       :with => "'postcode=' + encodeURIComponent($('outbreak_incidents_attributes_0_location_attributes_postcode').value)") %>