[RUBY] Lerndatensatz, der die Tweet-Funktion mit dem STI-Muster erstellt hat

Der Inhalt dieses Artikels wartet derzeit auf eine Überprüfung und kann sich ändern!

Was ist STI (Single Table Vererbung)?

Lassen Sie buchstäblich eine Tabelle von der übergeordneten Klasse an die untergeordnete Klasse erben! In diesem Fall ist der Elternteil Tweet → Kind Mediatweet`` Texttweet. Klassen für Medien-Tweets bzw. Text-Tweets!

Da die Tabellen jedoch identisch sind, haben alle Klassen, sowohl Eltern als auch Kinder, dieselben Spalten. Also hat Mediatweet auch einecontent Spalte und ** Texttweet hat auch eineimg Spalte. ** **.

db/schema.rb


  create_table "tweets", options: hogehoge
    t.text "content"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "img"
    t.integer "user_id"
    t.string "type"
  end

Warum machst du das

Es wird einfacher sein, die Unterschiede im Modell zu schreiben. Wenn Sie beispielsweise nur im Text-Tweet eine Validierung ohne Leerzeichen schreiben, kann das Bild ohne Text getwittert werden. Da der Inhalt jedoch fast identisch ist, ist STI, das die Tabelle gemeinsam nutzen kann, gut.

Implementierungsmethode

  1. Es befand sich bereits in db / schema.rb, aber lassen Sie die übergeordnete Klasse (Tabelle) eine Typ -Spalte (Zeichenfolgentyp) haben.
  2. Machen Sie jedes Modell. Erstellen Sie das übergeordnete Modell mit "Rails g Model" usw. und erstellen Sie das untergeordnete Modell usw. direkt in "app / model /"

models/tweet.rb


class Tweet < ApplicationRecord
end

models/mediatweet.rb


class Mediatweet < Tweet
end

models/texttweet.rb


class Texttweet < Tweet
end

Dies ist vorerst das Ende der STI-Implementierung. Der Rest wird automatisch erledigt. Wenn Sie beispielsweise die Datenbank bei "Mediatweet.create" usw. registrieren, wird der Spalte "type" ein Datensatz mit "Mediatweet" und Daten hinzugefügt.

Modellverteilung basierend auf dem Inhalt von Parametern, die von form_with erfasst wurden

Ich möchte die Modelle automatisch sortieren, je nachdem, ob Mediendaten vorhanden sind. Deshalb habe ich sie wie folgt implementiert.

index.html.erb


<%= form_with model: @tweet, url: tweets_path do |form| %>
  <%= form.text_area :content %><br>
  <%= form.label "Bild hochladen" %><br>
  <%= form.file_field :img %>
  <%= form.submit 'Post' %><br>
<% end %>

Diesmal handelt es sich um eine Beitrags- und Listenseite mit einem Beitragsformular wie im Index. Der Bild-Uploader ist in "carriewave" implementiert. Ich werde das weglassen. Die Parameter, die durch Senden aus dem obigen Formular übermittelt werden, sind

{
"authenticity_token"=>"hoge", 
"tweet"=>{"content"=>"hoge", "img"=>"hoge"}, 
"commit"=>"Post"
}

Sie können die Parameter einer solchen Doppelstruktur abrufen (eine Struktur mit {} innerhalb von {}).

Und es stimmt automatisch mit der Erstellungsaktion des Controllers überein

tweets_controller.rb


  def create
    @tweet = tweettype_class.new(tweet_params)
    if @tweet.save
      redirect_to("/tweets")
    else
      @tweets = Tweet.all.order(created_at: :desc)
      render("index")
  #Das Rendern kehrt zur ursprünglichen Seite der Beitragsliste zurück_Wenn Sie die URL von mit nicht angeben
  #form_Die Wurzel von with wird vom untergeordneten Modell gezogen und es tritt ein Fehler auf (z)Ehemalige Zitzen_Pfad Nach dem Rendern → Text-Tweets_Weg ist nicht viel.
    end
  end
  private

  def tweet_params
  #Nur der Teil, in dem der Schlüssel tweet ist, wird nach Bedarf extrahiert({"content"=>"hoge","img"=>"hoge"})
    params.require(:tweet).permit(:content, :img).merge(user_id: @current_user.id)
  end
  #[:img]Modelle werden nach Vorhandensein oder Nichtvorhandensein von Daten sortiert
  #Da es eine doppelte Struktur hat, kann der Wert nur dann korrekt abgerufen werden, wenn der Schlüssel auch zweimal angegeben wird.
  def tweettype
    case
    when params[:tweet][:img].present?
      'mediatweet'
    when params[:tweet][:img].blank?
      'texttweet'
    end
  end
  #Konvertieren Sie die empfangene Zeichenfolge in einen Kamelfall,Außerdem wird es in einen konstanten Namen konvertiert
  #(Beispiel) mediatweet.cmelize=>Mediatweet.constantize=>Mediatweet(id: integer, content: text, created_at: datetime, hogehoge.... )
  def tweettype_class
    tweettype.camelize.constantize
  end

Auf diese Weise habe ich versucht, die Modelle automatisch zu sortieren, je nachdem, ob das Bild hochgeladen wurde.

Dies macht es einfacher, für jedes Modell unterschiedliche Rollen zu schreiben!

Recommended Posts

Lerndatensatz, der die Tweet-Funktion mit dem STI-Muster erstellt hat
[Java] Implementieren Sie eine Funktion, die eine im Builder-Muster implementierte Klasse verwendet