Der Inhalt dieses Artikels wartet derzeit auf eine Überprüfung und kann sich ändern!
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
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.
db / schema.rb
, aber lassen Sie die übergeordnete Klasse (Tabelle) eine Typ
-Spalte (Zeichenfolgentyp) haben.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.
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!