2010-11-25 3 views
0

Ich habe die folgenden drei Modelle (Rails 2.3.8)Mit accepts_nested_attributes_for auf einer Join-Tabelle mit eigenen Attributen - Doppelte Zeilen

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 

Die Parameter aus dem Formular scheint in Ordnung zu sein

"Ausbruch" => { "locations_attributes" => {"0" => {"lon" => "- 1.39", "placename" => "wetwe", "hpu_id" => "15", "Postleitzahl" => "so1 1aa", "region_id" => "10", "adresse_1" => "", "stadt" => "Bargate", "adresse_2" => "", "adresse_3" => "", " lat "=>" 50.89 "}}," Vorkommnisse_Attribute "=> {" 0 "=> {" Untertyp_ID "=>" 7 "," Kategorie_ID "=>" 1 "," Detail "=>" " „Subcategory_id“ => „2“}}}

Aber wenn der Ausbruch gespeichert 3 Zeilen werden in den Vorfall Tabelle (die Join-Tabelle) und eine einzelne Zeile in der Ausbruch und Location-Tabellen erstellt.

Die Zeilen in den Vorfall Tabelle nicht vollständig von dem params bevölkerten wie folgt:

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 

Diese accepts_nested_attributes_for Methoden das entweder das Format der Parameter oder mehr fällig muss - wie muß ich nur Eine einzelne Zeile wird in die Incidents-Tabelle mit allen Parameterinformationen eingegeben?

Antwort

2

zum zweiten Mal so weit diese Woche habe ich meine eigene Frage beantwortet haben ^^, dass mir beibringen werde in um Hilfe, bevor er aufgibt und Buchung im Netz mehr Mühe zu geben,

Noch nach an meinem ursprünglichen suchen Frage ich habe enthalten nicht genügend Informationen um es richtig zu beantworten - das Problem (abgesehen von dem Aufbau der Modelle) war bis zum Ausbruch Konstruktor in der Outbreak-Controller neue Methode,

Original-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 

Überarbeitet 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 

Änderungen an den drei Modellen

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 

Diese ok scheint zu funktionieren - auch gepostet die Aktion erstellen und Hauptformular

+0

Vielen Dank dafür sein könnte, wie ich mit bidirektionaler Mappings am struggeling mit: durch so gut ... aber könnten Sie schreiben Ihre Aktionen erstellen und auch Formen, wenn möglich (nur zu Informationszwecken)? – tbk

+0

Sicher werde ich versuchen, etwas aufzustellen - die Formulare sind zwar etwas komplex (eine Anzahl verschachtelter Teiltöne), also werde ich als neue Antwort posten – Pasted

1

Die Aktion erstellen, benötigt nur die verschachtelten params vorgesehen: Ausbruch (Die Modelle machen die Arbeit).

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 

Der Ausbruch Form ist ziemlich lang, so habe ich es auf den beiden Abschnitten erwähnten abgeholzt (obwohl es wahrscheinlich mehr Attribute und Felder ist hier als eine Vorstellung bekommen müssen, ist).

Ein Beispiel für die HTML-Element-ID für die verschachtelten Felder finden Sie unten im Javascript-Operator "observe_field". Ein Beitrag habe ich auf AJAX-Updates von nested_attributes_for partials machte auch nützlich 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)") %> 
Verwandte Themen