[RUBY] So speichern Sie gleichzeitig Daten in einem Modell, das einem verschachtelten Formular zugeordnet ist (Rails 6.0.0)

Schlussfolgerung Fügen Sie dem übergeordneten Modell accept_nested_attributes_for hinzu

Demonstrationsumgebung

・ Cloud9 Ubuntu Server ・ Schienen 6.0.0 ・ Ruby 2.6.3p62 (16.04.2019, Revision 67580) [x86_64-linux]

Voraussetzungen

Angenommen, Sie haben ein Elternmodell und ein Kindermodell mit Eins-zu-Viele-Beziehungen wie folgt:

models/parent.rb


class Parent < ApplicationRecord
  has_many :kids, dependent: :destroy
end

models/kid.rb


class Kid < ApplicationRecord
  belongs_to :parent
end

Implementierung verschachtelter Formulare

Da die Daten des untergeordneten Modells gleichzeitig mit den Daten des übergeordneten Modells gespeichert werden, akzeptiert `` `akzeptierte_verschachtelte_Attribute_für``` Zum übergeordneten Modell.

models/parent.rb


class Parent < ApplicationRecord
  has_many :kids, dependent: :destroy
  accepts_nested_attributes_for :kids
end

Auf diese Weise können Sie verschachtelte Formulare verwenden, mit denen Sie die zugehörigen Daten in einem Formular registrieren können.

Erstellen Sie als Nächstes im übergeordneten Controller des übergeordneten Modells eine leere Instanz, die die von der Formularseite gesendeten Parameter empfängt.

Außerdem wird eine leere Instanz des zugeordneten untergeordneten Modells erstellt. Auch im starken Parameter, um die Kinderwagen des untergeordneten Modells zu erhalten

kids_attributes: [:name, :age, :toy]


 Geht vorbei.


#### **`controllers/parents_controller.rb`**
```rb

class ParentsController < ApplicationController

#(Weggelassen)
  
  def new
    @parent = Parent.new
    @parent.kids.build #Erstellen Sie eine leere Instanz des untergeordneten Modells
  end
  
  def create
    @parent = Parent.new(parent_params)
    if @parent.save
      redirect_to root_url
    else
      render :new
    end
  end

#(Unterlassung)
  
  private
  
    def parent_params
      #Ermöglicht den Empfang von Parametern für untergeordnete Modelle
      params.require(:parent).permit(
        :name, :age, kids_attributes: [:name, :age, :toy] 
      )
    end

end

erb:new.html.erb


<div class="container">
  <div class="col-sm-10 col-sm-offset-1">
    <h1 class="text-center">Elternregistrierung</h1>
    <%= form_with(model: @parent, local: true) do |f| %>
      <div class="field form-group">
        <%= f.label :name %>
        <%= f.text_field :name, class: "form-control" %>
      </div>
      <div class="field form-group">
        <%= f.label :age %>
        <%= f.number_field :age, class: "form-control" %>
      </div>

      <!--Verschachteltes Formular zum Empfangen von Daten für untergeordnete Modelle-->

      <%= f.fields_for :kids do |kf| %>
      <h1 class="text-center">Kinderregistrierung</h1>
        <div class="field form-group">
          <%= kf.label :name %>
          <%= kf.text_field :name, class: "form-control" %>
        </div>
        <div class="field form-group">
          <%= kf.label :age %>
          <%= kf.number_field :age, class: "form-control" %>
        </div>
        <div class="field form-group">
          <%= kf.label :toy %>
          <%= kf.text_field :toy, class: "form-control" %>
        </div>
      <% end %>

      <div class="field form-group">
        <%= f.submit "Registrieren Sie sich mit den oben genannten Inhalten", class: "btn btn-primary btn-lg btn-block" %>
      </div>
    <% end %>
  </div>
</div>

Es ist schwer zu erkennen, da es die Bootstrap-Klasse enthält, aber das obige `` `f.fields_for``` ist das Formular, das die Daten des untergeordneten Modells empfängt. ネストされたフォーム

Ermöglicht das Speichern neuer zugeordneter Daten beim Aktualisieren von Daten

Obwohl es sich um ein Eingabeformular für untergeordnete Modelle handelt, können Sie durch Erstellen mehrerer leerer Instanzen die Anzahl der Eingabefelder erhöhen, ohne die Ansichtsform selbst zu erhöhen. Wenn Sie beispielsweise den Eltern-Controller wie folgt ändern, können bei der Neuregistrierung ein Satz untergeordneter Modelleingabeformulare angezeigt werden, und beim Aktualisieren können zwei Sätze untergeordneter Modelleingabeformulare angezeigt werden.

controllers/parents_controller.rb


class ParentsController < ApplicationController

#(Unterlassung)

  def new
    @parent = Parent.new
    @parent.kids.build #Erstellen Sie eine leere Instanz des untergeordneten Modells
  end
  
  def create
    @parent = Parent.new(parent_params)
    if @parent.save
      redirect_to root_url
    else
      render :new
    end
  end

#(Unterlassung)

  def edit
    @parent = Parent.find(params[:id])
    @parent.kids.build #Erstellen Sie eine leere Instanz des untergeordneten Modells
  end
  
  def update
    @parent = Parent.find(params[:id])
    if @parent.update(parent_params)
      redirect_to root_url
    else
      render :edit
    end
  end
  
  def destroy
    @parent = Parent.find(params[:id])
    @parent.destroy
    redirect_to root_url
  end
  
  private
  
    def parent_params
      params.require(:parent).permit(
        :name, :age, kids_attributes: [:name, :age, :toy]
      )
    end
    
end

Durch Erstellen einer leeren Instanz des untergeordneten Modells in der Bearbeitungsaktion werden zum Zeitpunkt der Aktualisierung "registrierte untergeordnete Modelldaten" + 1 Eingabeformular erstellt.

Dies macht es einfacher, die Anzahl der Eingabeformulare zu erhöhen, als sie dynamisch mit JS hinzuzufügen. (Der Engpass ist, dass die Anzahl begrenzt ist ...)

Wenn Sie weitere Formulare hinzufügen möchten, können Sie weitere leere Instanzen erstellen.

@parent.kids.build


 Von

#### **`n.times { @parent.kids.build }`**

Auf diese Weise können Sie n Eingabeformulare generieren.

Verhindert, dass leere Daten gespeichert werden, wenn sie nicht eingegeben werden

So wie es ist, werden leere Daten gespeichert, wenn das hinzugefügte Formular nicht ausgefüllt wird. Um dies zu verhindern, übergeben Sie den folgenden Proc an das zweite Argument von `` `accept_nested_attributes_for```, das dem übergeordneten Modell hinzugefügt wurde.

models/parent.rb


class Parent < ApplicationRecord
  has_many :kids, dependent: :destroy
  accepts_nested_attributes_for :kids, reject_if: lambda {|attributes| attributes['name'].blank?}
end

Wenn im obigen Fall der Name des Eingabeformulars für das untergeordnete Modell leer ist, werden alle anderen Attribute (hier Alter, Spielzeug) nicht gespeichert, selbst wenn sie eingegeben werden.

Wenn Sie sich nicht registrieren möchten, wenn Name oder Alter nicht eingegeben wurden, ändern Sie dies wie folgt.

models/parent.rb


class Parent < ApplicationRecord
  has_many :kids, dependent: :destroy
  accepts_nested_attributes_for :kids, reject_if: lambda {|attributes| attributes['name'].blank? || attributes['age'].blank?}
end

Darüber hinaus können Sie die gespeicherten Werte frei steuern, indem Sie die Validierung in das untergeordnete Modell ändern.

Darüber hinaus kann es Fälle geben, in denen Sie nur die Daten des zugeordneten untergeordneten Modells löschen möchten. Weitere Informationen finden Sie im Rails-Handbuch unter "Action View Form Helper". Es wird hilfreich sein.

Nachwort

Ich bin Tatsuron, ein Anfänger, der gerade Ruby on Rails lernt. Ich habe über die Funktionen geschrieben, die beim Erstellen meiner eigenen App mehrere Tage lang hängen geblieben sind. Wenn Sie Fehler oder Ratschläge haben, kommentieren Sie bitte.

Recommended Posts

So speichern Sie gleichzeitig Daten in einem Modell, das einem verschachtelten Formular zugeordnet ist (Rails 6.0.0)
So benennen Sie ein Modell mit externen Schlüsseleinschränkungen in Rails um
So fügen Sie ein Video in Rails ein
So erhalten Sie den Wert von Boolean mit jQuery in einfacher Rails-Form
[Rails] Ich möchte Daten verschiedener Modelle in einem Formular senden
So implementieren Sie eine ähnliche Funktion in Rails
So erstellen Sie einfach ein Pulldown mit Rails
So erstellen Sie eine eindeutige Datenkombination in der Schienen-Zwischentabelle
So löschen Sie alle Daten in einer bestimmten Tabelle
So implementieren Sie eine nette Funktion in Ajax mit Rails
So löschen Sie ein mit Rails erstelltes new_record-Objekt
So generieren Sie manuell ein JWT mit Knock in Rails
So erstellen Sie einen Daten-URI (base64) in Java
So schreiben Sie eine Datumsvergleichssuche in Rails
Abfragen von Arrays in jsonb mit Rails + postgres
[Rails 6] So legen Sie ein Hintergrundbild in Rails [CSS] fest
[Rails] So laden Sie JavaScript in einer bestimmten Ansicht
Umgang mit Fehlern in Rails s konnte keine JavaScript-Laufzeit finden.
Speichern von Zeichenfolgen von ArrayList zu Zeichenfolge in Java (Personal)
So zeigen Sie Diagramme in Ruby on Rails an (LazyHighChart)
So fügen Sie dieselben Indizes in ein verschachteltes Array ein
Zuordnung zu einer Klasse mit einem Wertobjekt in How to My Batis
So simulieren Sie das Hochladen von Post-Object-Formularen in OSS in Java
So richten Sie einen Proxy mit Authentifizierung in Feign ein
So schreiben Sie in die Modellklasse, wenn Sie mit PlayFramework Binärdaten in der Datenbank speichern möchten
Implementieren Sie ein Kontaktformular in Rails
So installieren Sie jQuery in Rails 6
So installieren Sie Swiper in Rails
So erstellen Sie eine JAR-Datei ohne Abhängigkeiten in Maven
[Rails 6] So erstellen Sie mit cocoon einen dynamischen Formular-Eingabebildschirm
[Rails] So zeigen Sie übergeordnete Informationen in der untergeordneten Ansicht in verschachtelten Beziehungen an
So löschen Sie große Datenmengen in Rails und Bedenken
Speichern der im Textbereich eingegebenen Informationen in einer Variablen in der Methode
So implementieren Sie Suchfunktionen in Rails
So ändern Sie den App-Namen in Rails
So implementieren Sie eine Diashow mit Slick in Rails (einzeln und mehrfach nacheinander)
[Für Anfänger] Ich möchte mit einem Auswahlbefehl automatisch vorregistrierte Daten in das Eingabeformular eingeben.
So erstellen Sie eine Abfrage mithilfe von Variablen in GraphQL [Verwenden von Ruby on Rails]
[Persönliches Memo] Interaktion mit dem Zufallszahlengenerator in Java
Verwendung von MySQL im Rails-Tutorial
So aktualisieren Sie Benutzeränderungen in Rails Devise, ohne ein Kennwort einzugeben
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 6.x)
[Rails] So erhalten Sie die aktuell mit devise angemeldeten Benutzerinformationen
[Rails] So konfigurieren Sie das Routing in Ressourcen
[Rails] So erstellen Sie eine Teilvorlage
So implementieren Sie Ranking-Funktionen in Rails
So löschen Sie Daten mit einem externen Schlüssel
So debuggen Sie die Verarbeitung im Ruby on Rails-Modell nur mit der Konsole
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 5.x)