Dies ist eine Fortsetzung des vorherigen Artikels zum Erstellen einer Antwortfunktion in Kapitel 14 des Rails-Lernprogramms.
Ich werde die zu erledigende Arbeit überprüfen und auswaschen. ・ Machen Sie einen Zweig mit Git ・ Test durchführen model、integration
Suchen Sie nach Text zum Hinzufügen einer Modellspalte. Sie können sehen, dass Sie in 9.1.1 Spalten mit Migration hinzugefügt haben.
Überlegen Sie, wie Sie die Anzeige durch Antwort im Modell erstellen können. Schauen wir uns die Spezifikationen noch einmal an. @reply sollte nur im Feed des Empfängers und im Feed des Absenders erscheinen. Denken Sie in drei Teilen darüber nach, je nachdem, wer es anzeigt. 1 Absender, 2 Empfänger, 3. Dritter (weder Absender noch Empfänger)
Da es sich um einen von mir geposteten Mikropost handelt, wird er auch mit der aktuellen Funktion angezeigt.
Es gibt zwei Möglichkeiten: Der Empfänger folgt dem Absender und der Empfänger nicht. Wenn der Empfänger dem Absender folgt, ist er in der aktuellen Funktion weiterhin sichtbar. Wenn der Empfänger dem Absender nicht folgt, wird er mit der aktuellen Funktion nicht angezeigt. Sie können sehen, dass wir hier Funktionen hinzufügen müssen.
Die Funktion besteht darin, in_reply_to anzuzeigen, wenn Sie gleich sind. Ich dachte, ich würde die Methode user.micrposts ändern, aber sie funktioniert nicht. Ich habe es nicht gepostet. Der Absender wird nicht ausgewählt und der Mikropost der Person wird nicht zurückgegeben. Egal wer gepostet hat Es ist eine Funktion, um alle Mikroposts anzuzeigen, die gleich in_reply_to sind.
Die Idee ist, dass das Risiko von Leistungsproblemen umso höher ist, je mehr Mikroposts Sie haben. Es scheint notwendig, einen Index als Gegenmaßnahme hinzuzufügen. Ich verstehe, dass es ein Risiko ist, nach einem alternativen Schlüssel zu suchen, anstatt nach einem Primärschlüssel.
Diese Implementierungsmethode zeigt an, wie Sie es erstellen, unabhängig davon, ob Sie dem Absender folgen. Daher habe ich festgestellt, dass es nicht erforderlich ist, die Fälle zu trennen.
Überlegen Sie sich als Nächstes, zu welcher Methode die Funktion hinzugefügt werden soll. In Listing 14.46 sieht die Feed-Methode im Benutzermodell gut aus. Es scheint, dass Sie die Bedingung mit where angeben können.
Wenn ein Dritter den Feed-Bildschirm des Empfängers anzeigt, wird die Antwort nicht angezeigt. Wenn Sie eine Funktion mit den oben genannten Spezifikationen erstellen, wird diese angezeigt. Daher muss eine Funktion hinzugefügt werden, die nicht angezeigt wird. Wenn Sie nicht gleich in_reply_to sind, können Sie es ausblenden. Zuerst dachte ich, ich sollte Änderungen an der Rückgabe der user.micrposts-Methode vornehmen. Wie ich oben erwähnt habe, fand ich die Fütterungsmethode beim Empfänger gut, so dass ich intuitiv der Meinung war, dass dieselbe Methode gut ist.
Lesen Sie noch einmal 14.3.2.
Wählen Sie in der Mikroposttabelle alle Mikroposts aus, deren ID dem Benutzer entspricht, dem ein Benutzer (dh er selbst) folgt.
Wählen Sie in der Mikroposttabelle alle Antworten aus, deren Empfänger Sie sind.
SELECT * FROM microposts
WHERE user_id IN (<list of ids>)
OR user_id = <user id>
OR in_reply_to = <user id>
Ich denke, es sollte getan werden.
Listing 14.44
def feed
Micropost.where("user_id IN (?) OR user_id = ? OR in_reply_to = ?", following_ids, id,id)
end
Sieht gut aus.
Ich urteile, dass die Spezifikationen damit unterdrückt wurden, und entscheide mich, es zu machen.
Erstellen Sie wie gewohnt einen Zweig.
ubuntu:~/environment/sample_app (master) $ git checkout -b reply-micropost
Im Text erfahren Sie, wie Sie dem Modell Spalten hinzufügen. 6.3.1 Ich habe eine Spalte mit "Hashed Password" hinzugefügt. Mach es auf die gleiche Weise.
ubuntu:~/environment/sample_app (reply-micropost) $ rails generate migration add_reply_to_microposts in_reply_to:integer
db/migrate/20201003003147_add_reply_to_microposts.rb
class AddReplyToMicroposts < ActiveRecord::Migration[5.1]
def change
add_column :microposts, :in_reply_to, :integer
end
end
Erstellen Sie als Nächstes einen Modelltest. 13.1.2 Gehen Sie genauso vor wie bei der Micropost-Validierung. Was das zu testende Modell betrifft, habe ich dem Mikropost eine Spalte hinzugefügt, daher denke ich, dass es Mikropost ist.
Erstellen Sie einen Antwort-Mikropost basierend auf dem Absender und dem Empfänger der Antwort.
Wenn Sie antworten, ist der auf dem Feed-Bildschirm angezeigte Test der Integrationstest. Überlegen Sie sich vorher, was Sie mit dem Modelltest testen möchten.
Als Test für die Funktion der durch Antwort hinzugefügten Methode scheint das Aktualisieren und Löschen nicht in CRUD enthalten zu sein. Sie müssen daher eine Antwort erstellen und lesen. Ich werde es auf der Konsole versuchen.
>> user2.microposts.create!(content: "test2", in_reply_to: 1 )
>> user2.microposts.create!(content: "test3", in_reply_to: 1 )
>> Micropost.where(in_reply_to: 1)
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."in_reply_to" = ? ORDER BY "microposts"."created_at" DESC LIMIT ? [["in_reply_to", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Micropost id: 304, content: "test3", user_id: 30, created_at: "2020-10-03 02:37:38", updated_at: "2020-10-03 02:37:38", picture: nil, in_reply_to: 1>, #<Micropost id: 303, content: "test2", user_id: 30, created_at: "2020-10-03 02:18:35", updated_at: "2020-10-03 02:18:35", picture: nil, in_reply_to: 1>]>
Wenn die vorhandene Methode ausreicht, scheint das Testen nicht erforderlich zu sein, da das Modell keine Funktionen hinzufügt, aber ich werde es vorerst schreiben.
test/models/micropost_test.rb
test "reply should be returned" do
@reply_post = @reply_sender.microposts.create!(content: "reply test1", in_reply_to: @user.id)
assert Micropost.where(in_reply_to: @user.id).include?(@reply_post)
end
Nachdem wir das Modell getestet haben, erstellen wir einen Integrationstest. Der Inhalt des Tests besteht darin, eine Antwort zu erstellen und diese auf dem Feed-Bildschirm des Empfängers anzuzeigen.
Überlegen Sie sich vorher, wo Sie die Änderungen vornehmen sollen. Ich dachte, ich müsste das Ergebnis testen, da ich Änderungen am Controller vornehmen würde.
Beginnen wir mit dem Integrationstest. Auf der Suche nach einem Test, der hilfreich zu sein scheint, sieht follow_test.rb gut aus. Außerdem wird der zu postende Ort basierend auf microposts_interface_test.rb kopiert.
test/integration/reply_test.rb RED
test "reply to user " do
log_in_as(@user)
content = "@reply #{@other.name} Cum aspermatur"
post microposts_path, params: { micropost: {content: content }}
log_in_as(@other)
get root_path
assert_not @other.following?(@user)
#get root_path
assert_match content, response.body
#assert_match content, response.body
end
Nehmen Sie Änderungen am Feed vor, um eine Antwort anzuzeigen.
Erstellen Sie zunächst Testdaten. Fügen Sie dem Gerät Daten hinzu.
test/fixtures/microposts.yml
tonton:
content: "@reply malory tonton is the name of the panda."
created_at: <%= Time.zone.now %>
user: michael
Wo soll der Feed getestet werden, aber ich denke, es ist ein Modelltest, da er sich zum Benutzermodell ändert.
test/models/user_test.rb RED
test "feed should have the reply posts" do
michael = users(:michael)
malory = users(:malory)
reply_post = microposts(:tonton)
assert michael.feed.include?(reply_post)
assert malory.feed.include?(reply_post)
puts reply_post.content
end
end
Ändern Sie den Feed.
app/models/user.rb
def feed
following_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
Micropost.where("user_id IN (#{following_ids})
OR user_id = :user_id
OR in_reply_to = reply_id",
user_id: id,
reply_id: id )
end
tonton:
content: "@reply malory tonton is the name of the panda."
created_at: <%= Time.zone.now %>
user: michael
in_reply_to: <%= User.find_by(name: "Malory Archer").id %>
Das Ändern des Feeds führte dazu, dass andere Tests fehlschlugen. Siehe die Fehlermeldung.
ubuntu:~/environment/sample_app (reply-micropost) $ rails test test/models/micropost_test.rb
Running via Spring preloader in process 2886
Started with run options --seed 405
FAIL["test_order_should_be_most_recent_first", MicropostTest, 0.5243559590000189]
test_order_should_be_most_recent_first#MicropostTest (0.52s)
--- expected
+++ actual
@@ -1 +1 @@
-#<Micropost id: 941832919, content: "Writing a short test", user_id: 762146111, created_at: "2020-10-10 01:35:16", updated_at: "2020-10-10 01:35:17", picture: nil, in_reply_to: nil>
+#<Micropost id: 981300582, content: "@reply malory tonton is the name of the panda.", user_id: 762146111, created_at: "2020-10-10 01:35:17", updated_at: "2020-10-10 01:35:17", picture: nil, in_reply_to: 659682706>
test/models/micropost_test.rb:33:in `block in <class:MicropostTest>'
6/6: [===================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Ich erhalte die Fehlermeldung, dass ein Problem mit den Testdaten vorliegt. Ich denke, dass die Ursache darin besteht, dass die Testdaten mit der letzten Buchungszeit als most_recent in fixture erstellt wurden, aber tonton hatte eine neuere Buchungszeit. Es ist nicht erforderlich, die Buchungszeit zu aktualisieren. Korrigieren Sie daher die Buchungszeit von tonton.
test/fixtures/microposts.yml vor der Änderung
tonton:
content: "@reply malory tonton is the name of the panda."
created_at: <%= Time.zone.now %>
user: michael
test/fixtures/microposts.nach dem Ändern von yml
tonton:
content: "@reply malory tonton is the name of the panda."
created_at: <%= 2.minutes.ago %>
user: michael
in_reply_to: <%= User.find_by(name: "Malory Archer").id %>
Es wurde sicher repariert.
Stellen Sie sicher, dass der Mikropost mit @reply auf der Seite angezeigt wird. Erstellen Sie Beispieldaten unter Listing 13.25: "Hinzufügen von Mikroposts zu Beispieldaten".
db/seeds.rb
# reply
sender = users.first
reciever = users.second
reply_content = "@reply #{receiver.name} reply test"
sender.microposts.create!(content: reply_content,
in_reply_to: receiver.id )
Als ich den Rails-Server anhob und den Bildschirm anzeigte, wurde bestätigt, dass der Antwort-Mikropost angezeigt wurde.
7,0 Stunden von 10/2 bis 10/10.
Recommended Posts