2016-03-31 15 views
0

Ich habe ein Problem beim Speichern des Modells mit geschachtelte Attribute. In der App gibt es einen Kunden, die haben 1..n Kontakte Hexe wiederum haben 1..n Telefone.Verschachtelte Attribute Kindmodell nicht speichern

Ich habe viel gesucht, bevor Sie hier gefragt, und beschlossen, es zu speichern nur die Kontakt zuerst. Nun, zuerst wird der Kunde gespeichert, aber Kontakt ist nicht. Von dem, was ich lese es nicht notwendig ist, die zu wiederholen ... contacts.build von neuen Funktion imerstellen, und dass die Leitung „@customer = Customer.new (customer_params)“ schaffen würde und speichern Sie sie beide.

Warum funktioniert es nicht? (Das ist die erste Frage.)

Nach einigen Änderungen und Fehlersuche, fand ich, dass, wenn ich eine zweite Linie Gebäude Kontaktsatz (... contacts.build (customer_params [: contacts_attributes])) nicht gespeichert ist wegen eines Fehlers von 'unbekanntes Attribut'. Das liegt daran, dass zwischen dem Hash: contacts_attribute und seinem Inhalt ein weiterer Hash mit dem Namen ': 0' (?) Hinzugefügt wurde. Die Struktur des Hash, der aus der Form kommt, ist dies:

": contacts_attribute [: 0 [: Name,: Abteilung: E-Mail]]"

Ich stelle mir vor, dass dieser Hash: 0 ist für mehr als ein Kontakt Instanz hinzufügen, die in Hashes kommen: 1, 2 usw.

Es gibt einen Weg zum speichern der Kontakt Beispiel, indem sie diese: 0 Hash? (? Wie kann ich diesen Hash Ist es "...: contacts_attribute [0]"?)

Unterhalb der entsprechende Code ist. Danke für die Aufmerksamkeit!

customer.rb

class Customer < ActiveRecord::Base 
...  
has_many :contacts 
accepts_nested_attributes_for :contacts, reject_if: lambda {|attributes| attributes['kind'].blank?} 
... 
def change_by(user_id) 
    update_attributes(changed_by: user_id, deleted_at: Time.now, updated_at: Time.now) 
end 

def delete(user_id) 
    update_attributes(status: false, changed_by: user_id, deleted_at: Time.now, updated_at: Time.now) 
end 

private 
... 
end 

customers_controller.rb

class CustomersController < ApplicationController 

def new 
    @customer = Customer.new 
    @customer.contacts.new 
end 

def create 
    user_id = session[:user_id] 
    @customer = Customer.new(customer_params) 
    if @customer.save 
    @customer.change_by(user_id) 
    flash[:success] = "Cliente cadastrado com sucesso!" 
    redirect_to customers_url 
    else 
    render 'new' 
    end 
end 

private 

def customer_params 
    params.require(:customer).permit(:razao_social, :nome, :CPF_CNPJ, 
       :adress_id, :email_nota, :transporter_id, :observacao, 
       contacts_attributes: [:nome, :setor, :email]) 
end 

Formular

<div class="row"> 
<div class="col-md-6 col-md-offset-3"> 
    <%= form_for @customer do |f| %> 
    <%= f.label "Dados Básicos" %> 
    <div class="well">  
    <%= f.label :razao_social, "Razão Social" %> 
    <%= f.text_field :razao_social %> 

    <%= f.label :nome, "Nome" %> 
    <%= f.text_field :nome %> 

    <%= f.label :CPF_CNPJ, "CPF/CNPJ" %> 
    <%= f.text_field :CPF_CNPJ %> 

    <%= f.label :email_nota, "Email para nota" %> 
    <%= f.email_field :email_nota %> 

    <%= f.label :observacao, "Observações" %> 
    <%= f.text_area :observacao %> 
    </div> 

    <%= f.fields_for :contacts do |k| %> 
     <%= k.label "Contato" %> 
     <div class="well"> 
     <%= k.label :nome, "Nome" %> 
     <%= k.text_field :nome %> 

     <%= k.label :setor, "Setor" %> 
     <%= k.text_field :setor %> 

     <%= k.label :email, "Email" %> 
     <%= k.email_field :email %> 

     </div> 
    <% end %> 
    <%= f.submit "Cadastrar Cliente", class: "btn btn-primary" %> 
    <% end %> 
</div> 

Antwort

0
reject_if: lambda {|attributes| attributes['kind'].blank?} 

Keine Spur von :kind in Ihrem Formular oder Ihrem customer_params

Das könnte etwas damit zu tun haben.

Wenn Sie eine Add/Remove-Beziehung für Kontakte benötigen, sollten Sie sich das cocoon Juwel ansehen. Wenn Sie nur ein benötigen, bauen dann, dass in Ihre Felder für:

<%= f.fields_for :contacts, @customer.contacts.first || @customer.contacts.build do |k| %> 

Die Form wird dann spezifisch für eine einzelne Instanz Kontakt.

Es gibt eine Möglichkeit, die Contact-Instanz zu speichern, indem Sie Folgendes erhalten: 0 Hash? (Wie greife ich auf diesen Hash Ist es "...: contacts_attribute [0]"?)

Sie brauchen nicht darauf zugreifen, das ist, was die accepts_nested_attributes für ist. Der Rest des Codes sieht gut aus, also sortiere das Problem der Ablehnung oben aus und komm zurück, wenn noch Probleme bestehen, und poste die Log-Ausgabe - speziell den Params-Hash für die Anfrage!

+0

Hey, Matt! Vielen Dank! Das war das Problem ... Es funktioniert perfekt mit dem Kunden + Kontakt, aber ich habe keine Ahnung, wie das Telefon im Kunden erklärt wird. Es hat eine Zuordnung * gehört zu * mit Kontakt, nicht mit dem Kunden . Wie kann ich es mit den anderen beiden speichern? –

+0

@LeandroPonsMalheiros Wenn es unter dem Kontakt verschachtelt ist, tun Sie genau dasselbe wie für den Kontakt, 'fields_for: telephone' und' accept_nested_attributes' dafür im Kontaktmodell. – Matt

+0

@LeandroPonsMalheiros Wenn dies geholfen hat, akzeptieren Sie bitte die Antwort, um die Frage zu schließen. – Matt

Verwandte Themen