2016-07-21 25 views
0

Ich versuche, eine Art der Umkehrung von 'access_nested_attributes' zu tun. Ich möchte eine Elterninstanz von einem 'children_controller # create' erstellen. Vielleicht hast du einen Rat oder erklärst du mir, dass das nicht relevant ist. Ich bin offen für jeden Kommentar!Rails - Erstelle übergeordnete Instanz von untergeordneten Formular

Ich habe ein Client-Modell:

class Client < ActiveRecord::Base 
    has_one :magazine 
    validates :name, presence: true, uniqueness: true 
end 

und ein Magazin Modell:

class Magazine < ActiveRecord::Base 
    belongs_to :client 
    validates :client, :launch_date, presence: true 
    # accepts_nested_attributes_for :client 
end 

Ich verwende reagieren Schienen gem und in /magazines habe ich ein Formular ein neues Magazin zu schaffen, mit ein Textfeld, um den Client-Namen anzugeben.

In meinem magazines_controller.rb habe ich die folgenden

def create 
    @client = Client.find_by_name(magazine_params[:client_id]) 
    @selected_magazine = Magazine.new(magazine_params) 
    authorize @selected_magazine 
    if @client 
    @selected_magazine.client = @client 
    else 
    @client = Client.new(name: magazine_params[:client_id]) 
    @client.save 
    @selected_magazine.client = @client 
    end 
    # @client = Client.where(name: magazine_params[:client_id]).first_or_create 
    # @selected_magazine.client = @client if @selected_magazine.client_id.to_i == 0 
    @title = magazine_params[:title] 
    @selected_issue = nil 
    @issues = nil 
    @selected_magazine.save 
    binding.pry 
    @magazines = policy_scope(Magazine) 
end 

def magazine_params 
    magazine_params = params.require(:magazine).permit(:title, :analytics_id, :launch_date, :client_id) 
    # if @client 
    # params[:magazine][:client_id] = @client.id 
    # magazine_params.merge!(params[:magazine]) 
    # end 
    return magazine_params 
end 

ich immer mit einem PG :: Fehlern am Ende:

PG::ForeignKeyViolation - ERROR: insert or update on table "magazines" violates foreign key constraint "fk_rails_cd907cfe6d" 
DETAIL: Key (client_id)=(51) is not present in table "clients". 

Als ob der Kunde nicht in der Datenbank speichern wurde. Wenn ich binding.pry und Client.allafter @client.save aufrufen, gibt es meinen neuen Client nicht zurück.

Ich bin ein wenig überrascht, da ich in einem anderen Projekt ein ähnliches Problem hatte und es funktionierte gut. Zu Ihrer Information:

# Previous Project 
# Gemfile.lock 
pg (0.18.3) 
rails (4.2.0) 

#Current Project 
# Gemfile.lock 
pg (0.18.4) 
rails (4.2.5.1) 

Vielen Dank im Voraus für Ihre Hilfe. Wenn Sie Ratschläge zu bewährten Verfahren zum Erstellen einer übergeordneten Instanz vor dem Kind von children_controller haben, bin ich wirklich interessiert.

PS1: In der Steuerung habe ich versucht mit den kommentierten zuerst oder create und die Ausgabe ist immer noch gleich. PS2: Lassen Sie mich wissen, wenn Sie mehr Informationen über Gemfile benötigen.

+0

Können Sie dies für das tatsächliche Implementieren beziehen Übernahme von verschachtelten Attributen. https://www.sitepoint.com/complex-rails-forms-with-nested-attributes/ –

+0

Zuerst stellen Sie sicher, dass Sie eine Instanz von "Client" erhalten, verwenden Sie nicht die alte Syntax 'Client.find_by_name (magazine_params [: client_id]) ', benutze etw wie folgt: ' Client.where (name: magazine_params [: client_id]). zuerst! ' Zweitens, stelle sicher, dass' Client' Instanz gespeichert ist, kannst du 'aufrufen @ client.save! 'für diesen Zweck. – BitOfUniverse

+0

@VaibhavDhoke, ich versuche, die Umkehrung der verschachtelten Attribute zu tun, die von Eltern zu Kind geht [link (http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html). Wenn ich Ihr Beispiel nehme, möchte ich einen Benutzer aus einem Adressformular mit Eins-zu-eins-Verknüpfung erstellen – MaxDpt

Antwort

1

Sie möchten inverse_of auf Verbände, zum Beispiel, um zu versuchen:

class Client < ActiveRecord::Base 
    has_one :magazine, inverse_of: :client 
    validates :name, presence: true, uniqueness: true 
end 

und

class Magazine < ActiveRecord::Base 
    belongs_to :client, inverse_of: magazine 
    validates :client, :launch_date, presence: true 
    # accepts_nested_attributes_for :client 
end 

Weiterführende Literatur: http://guides.rubyonrails.org/association_basics.html#bi-directional-associations

Der allgemeine Anwendungsfall, aber mit a has_many

0

Bitte versuchen Sie den folgenden Code, dies sollte das Problem beheben. Ich denke das Problem ist, dass Sie versuchen, das Magazin zu speichern, bevor Sie den Kunden retten. Außerdem sollten Sie überprüfen, ob @ client.valid? ist wahr, wenn nicht dann, überprüfen Sie @ client.errors. Außerdem den Controller wie folgt umschreiben:

def create 
    @client = Client.find_by_name(params[:magazine][:client_id]) 

    if @client.nil? 
    @client = Client.new(name: params[:magazine][:client_id]) 
    end 

    @selected_magazine = @client.magazines.new(magazine_params) 

    authorize @selected_magazine 

    @title = magazine_params[:title] 
    @selected_issue = nil 
    @issues = nil 

    @client.save 
    @magazines = policy_scope(Magazine) 
end 

def magazine_params 
    params.require(:magazine).permit(:title, :analytics_id, :launch_date) 
end 
+0

Relationen zwischen Client & Mag ist 'has_one <=> gehört_zu'so' @selected_magazine = @ client.magazines.new (magazine_params) 'löst einen Fehler aus. Wenn ich mich in zwei Zeilen aufspalte und singulare benutze, bekomme ich einen gültigen Client und ein ungültiges Magazin (keine client_id). Ich bekomme 'PG :: ForeignKeyViolation - FEHLER: aktualisieren oder löschen auf Tabelle" Clients "verletzt Fremdschlüssel Einschränkung" fk_rails_cd907cfe6d "auf Tabelle" Zeitschriften " DETAIL: Schlüssel (ID) = (55) wird immer noch aus Tabelle" Zeitschriften "referenziert. ' – MaxDpt

0

Sie können sich beziehen auf http://www.amooma.de/screencasts/2015-01-22-nested_forms-rails-4.2/. Gut erklärt mit Beispiel. Es kann Ihr Problem lösen.

+0

von dem, was ich gelesen habe accept_nested_attributes geht nur von Eltern zu Kind. Nicht umgekehrt (http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html), oder? – MaxDpt

+0

das ist auch mein Verständnis, obwohl ich nicht verstehe, warum das der Fall ist. Es gibt einige Anwendungsfälle, in denen Sie beim Erstellen des untergeordneten Objekts über das neue untergeordnete Formular ein übergeordnetes Element erstellen oder auswählen möchten. Gibt es einen besseren Weg, dies zu erreichen, anstatt accapsives_nested_attributes zu verwenden? Danke – BB500