代码之家  ›  专栏  ›  技术社区  ›  Pasted

在具有自己属性的联接表上使用accepts_nested_attributes_for-重复行

  •  1
  • Pasted  · 技术社区  · 15 年前

    我有以下三种型号 (轨道2.3.8)

        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
    

    表单中的参数似乎可以

    “爆发”=>{ “地理位置属性”=>{“0”=>{“lon”=>“-1.39”,“地名”=>“wetwe”,“hpu的身份”=>“15”,“邮政编码”=>“so1 1A A”,“地区的身份”=>“10”,“地址1”=>“,”城镇”=>“Bargate”,“地址2”=>“,”地址3”=>“,”lat”=>“50.89”};>“50.89”};“50.89”};“50.89”},“突发事件属性”=>{“0”=>“0”=>“0”=>“0”=>“0”=>“0”=>“15”,“15”,“15=>{“子类型id”=>“7”,“类别id”=>“1”,“详细信息”=>“”,“子类别id”=>“2”} }

    但是,保存爆发时,在事件表(联接表)中创建3行,在爆发和位置表中创建一行。

    事件表中的行未完全从参数填充,如下所示:

    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 
    

    这必须是由于参数的格式或方法的多个接受嵌套属性造成的-如何在事件表中只输入一行所有参数信息?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Pasted    15 年前

    到目前为止,这周我已经第二次回答了我自己的问题,这将教会我在放弃之前付出更多的努力,并在网上寻求帮助,

    在看了我最初的问题之后,我没有包含足够的信息来正确地回答它——问题(除了模型的设置)是由爆发控制器新方法中的爆发构造函数决定的,

    原发病控制者

    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
    

    修订疫情控制者

    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
    

    这似乎工作正常-还发布了创建操作和主窗体

        2
  •  1
  •   Community Mohan Dere    9 年前

    create操作只需要为:outbreak(模型完成工作)提供的嵌套参数。

    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 observate_field助手的底部找到。我在AJAX上为partials更新嵌套的属性也可能很有用 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)" ) %>
    
    推荐文章