Utilizzando accepts_nested_attributes_for su un join tabella con i propri attributi - righe duplicate

StackOverflow https://stackoverflow.com/questions/4279028

Domanda

Ho le seguenti tre modelli (Rails 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

I parametri dal modulo di sembrano essere ok

"focolaio" => { "Locations_attributes" => { "0" => { "lon" => "- 1,39", "toponimo" => "wetwe", "hpu_id" => "15", "Cap" => "1AA SO1", "region_id" => "10", "Indirizzo_1" => "", "città" => "Bargate", "Indirizzo_2" => "", "address_3" => "", "lat" => "50.89" }}, "incidents_attributes" => { "0" => { "subtype_id" => "7", "category_id" => "1", "dettaglio" => "", "subcategory_id" => "2"} } }

Ma quando l'epidemia è salvato 3 file vengono creati nella tabella Incidenti (la tabella join) e una singola riga nel focolaio e tavoli Posizione.

Le righe della tabella incidenti non sono completamente compilata dalle params come segue:

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 

Questo deve essere dovuto alla sia il formato dei parametri o multiplo accepts_nested_attributes_for metodi -? Come posso avere solo una singola riga di essere inserito nella tabella Incidenti con tutte le informazioni parametri

È stato utile?

Soluzione

La seconda volta finora in questa settimana ho risposto alla mia domanda ^^ che ti insegnarmi a fare uno sforzo maggiore nella prima di rinunciare e la pubblicazione in rete per aiuto,

Ancora dopo aver guardato la mia domanda iniziale non ho incluso informazioni sufficienti per rispondere in modo corretto - il problema (a parte la messa a punto dei modelli) è sceso al costruttore Outbreak nel controller Outbreak nuovo metodo,

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

Revised Outbreaks_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

Le modifiche ai tre modelli

    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

Questo sembra funzionare bene - anche postato il creare l'azione e la forma principale

Altri suggerimenti

L'azione ha solo bisogno di creare i params annidati previste: scoppio (i modelli fanno il lavoro)

.
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

La forma epidemia è piuttosto lunga così ho tagliato verso il basso per le due sezioni citate (anche se non c'è probabilmente più attributi e campi qui che è necessario per avere un'idea).

Un esempio della id dell'elemento HTML per i campi nidificati possono essere trovate in fondo nella observe_field helper Javascript. Un post che ho fatto sugli aggiornamenti AJAX di parziali nested_attributes_for potrebbe anche essere utile AJAX di 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)" ) %>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top