Dies ist eine Fortsetzung des Abschnitts zum Erstellen von Erweiterungen in Kapitel 14 des Rails-Lernprogramms.
Die Antwortfunktion wurde bis zum letzten Mal abgeschlossen. Der zweite Funktionszusatz besteht darin, eine Nachrichtenfunktion zu erstellen.
Für das Tutorial
Twitter unterstützt die Möglichkeit, Direktnachrichten zu senden. Lassen Sie uns diese Funktion in einer Beispielanwendung implementieren
Überprüfen Sie seitdem die Funktion von Twitter.
(Hinweis: Sie benötigen ein Nachrichtenmodell und einen regulären Ausdruck, der dem neuen Mikropost entspricht.)
Ist das Nachrichtenmodell eine Rails-Funktion? Ich werde es im Netz nachschlagen.
Überprüfen Sie zunächst die Funktion von Twitter.
Die andere Person muss Ihnen folgen, unter der Bedingung, dass Sie DM senden können. Ich werde diese Funktion später erstellen.
Es gibt auch eine Funktion zum Anzeigen des Lesens, aber diese Funktion wird aufgegeben.
Sie können festlegen, dass Push-Benachrichtigung / SMS-Benachrichtigung (Short Mail-Benachrichtigung) / Mail-Benachrichtigung empfangen wird, wenn Sie DM erhalten. Ich werde diese Funktion auch aufgeben.
Sie können DMs von bestimmten Konten auch stummschalten, um zu verhindern, dass sie Benachrichtigungen erhalten. Ich werde diese Funktion auch aufgeben.
Es gibt auch eine Funktion, um DM von einem bestimmten Konto abzulehnen. Sie können Ihren Gegner blockieren. Ich werde diese Funktion auch aufgeben.
Sie können die empfangenen DM löschen. Ich werde diese Funktion machen. Der Absender kann den DM nach dem Senden nicht mehr löschen.
DM und Post haben unterschiedliche Bildschirme.
Als ich untersuchte, ob die maximale Anzahl von Zeichen unterschiedlich war, waren es bis Juli 2015 140 Zeichen und danach 10.000 Zeichen. Dieses Mal werde ich 140 Zeichen verwenden.
Nachdem untersucht wurde, ob mehrere Ziele verwendet werden können, gab es eine Funktion zum Erstellen einer Gruppe und zum Sprechen mit mehreren Konten. Es wird gesagt, dass es im Januar 2015 abgeschlossen wurde, also werde ich diese Funktion aufgeben.
Ich verstand die Funktion von Twitter und konnte mir vorstellen, welche Funktion diesmal erstellt werden sollte.
Ich habe untersucht, ob das Nachrichtenmodell eine Funktion von Rails ist, konnte aber einen solchen Artikel nicht finden. Ich habe einen Artikel gefunden, um eine Chat-Funktion selbst zu erstellen, und einen Artikel, um einen Echtzeit-Chat zu erstellen, aber er scheint irrelevant zu sein.
Machen Sie Spezifikationen für das Modell. Lesen Sie das Tutorial erneut, in dem Sie einen Micropost erstellen. In Kapitel 13 erstellen wir zunächst ein Modell in 13.1. Ich werde auf die gleiche Weise ein Modell von DM machen.
Spaltenname | Attribut |
---|---|
id | integer |
content | text |
sender_id | integer |
receiver_id | integer |
created_at | datetime |
updated_at | datetime |
Abbildung DM-Modell
Hier bezieht sich der Empfänger auch auf das Benutzermodell. Ich denke, dass diese Beziehung dieselbe ist wie bei der Erstellung des folgenden Modells, daher habe ich das Tutorial erneut gelesen.
In Bezug auf das Löschen des Benutzers wird auch die Beziehung gelöscht. Ich habe beschlossen, es nicht in DM zu löschen. Das ist anders.
In Bezug auf Nicht entfernen wird auch die Beziehung entfernt. Selbst wenn der Empfänger in DM löscht, verschwindet der DM nicht und nicht vom Bildschirm des Absenders. Es verschwindet einfach vom Bildschirm des Empfängers. Lassen Sie uns darüber nachdenken, was dies bedeutet. Das Löschen von DM bedeutet nicht, dass es nicht durchgeführt wurde, aber die Tatsache, dass es gesendet wurde, bleibt bestehen. Wie beim E-Mail wird beim Senden der empfangenen E-Mail durch den Empfänger die gesendete E-Mail des Absenders nicht gelöscht. Ich habe es auf Twitter versucht und es war sicher.
Stellen Sie sich einen Eimer mit DM vor, wie eine E-Mail. Dies ist ein Modell, bei dem Sender und Empfänger separate Buckets haben. Wenn Sie eine DM senden, legen Sie eine in den Eimer des Absenders und eine in den Eimer des Empfängers. Ich fand, dass es ein Duplikat war, genau dieselbe Nachricht in zwei Eimer zu stecken.
Also behalte ich einen Bucket und füge ein Löschflag hinzu, damit der Empfänger weiß, dass er gelöscht wurde.
Ich suchte im Netz nach Attributen, um wahr oder falsch zu setzen, und stellte fest, dass es einen Booleschen Wert gab und dass ich immer den Standardwert setzen sollte. Der Grund ist, dass Null und Falsch in Rubin gleich behandelt werden. https://qiita.com/jnchito/items/a342b64cd998e5c4ef3d
Dies ist das modifizierte Modell.
Spaltenname | Attribut |
---|---|
id | integer |
content | text |
sender_id | integer |
receiver_id | integer |
deleted | boolean |
created_at | datetime |
updated_at | datetime |
Abbildung DM-Modell
Erstellen Sie einen Themenzweig.
ubuntu:~/environment/sample_app (master) $ git checkout -b create-dm
Generieren Sie ein dm-Modell.
ubuntu:~/environment/sample_app (create-dm) $ rails generate model dm content:text user:references
create db/migrate/20201102003220_create_dms.rb
create app/models/dm.rb
create test/models/dm_test.rb
create test/fixtures/dms.ymlrails generate mode dm content:text user:references
Ändern Sie die Migration. Ich habe den Index erstellt, weil es zwei Möglichkeiten gibt: Zum einen den Absender anzugeben und in Zeitreihen abzurufen und zum anderen den Empfänger anzugeben, der in Zeitreihen abgerufen werden soll. Für die Behandlung von null des gelöschten Flags habe ich auf den vorherigen Artikel im Internet verwiesen.
db/migrate/20201102003220_create_dms.rb
class CreateDms < ActiveRecord::Migration[5.1]
def change
create_table :dms do |t|
t.text :content
t.integer :sender_id
t.integer :reciever_id
t.boolean :deleted, default: false, null: false
t.timestamps
end
add_index :dms, [:sender_id, :created_at]
add_index :dms, [:receiver_id, :created_at]
end
end
Aktualisieren Sie die Datenbank.
ubuntu:~/environment/sample_app (create-dm) $ rails db:migrate
Assoziierter Benutzer und DM. Lesen Sie 14.1.2 "User / Relationship Association" im Tutorial.
app/models/user.rb
class User < ApplicationRecord
has_many :microposts, dependent: :destroy
has_many :active_relationships,class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
has_many :sent_dms,class_name: "Dm",
foreign_key: "sender_id"
has_many :received_dms,class_name: "Dm",
foreign_key: "receiver_id"
app/models/dm.rb
class Dm < ApplicationRecord
belongs_to :sender, class_name: "User"
belongs_to :receiver, class_name: "User"
end
Zeichnen Sie ein Diagramm, um die Beziehungen zu organisieren.
id | name |
---|---|
1 | Michael |
2 | Archer |
Benutzermodell
has_many
sender_id | receiver_id | content |
---|---|---|
1 | 2 | ... |
1 | 3 | ... |
dm Modell
has_many
id | name |
---|---|
2 | Archer |
3 | ... |
Benutzermodell Abbildung Benutzer- und DM-Beziehung
Folgende Methoden stehen zur Verfügung:
Methode | Verwenden |
---|---|
user.sent_dms | Gibt eine Reihe von DMs zurück, die vom Benutzer gesendet wurden |
sent_dms.sender | Gibt den Absender zurück |
sent_dms.receiver | Gibt den Empfänger zurück |
user.sent_dms.create(receiver_id: other_user.id) | Erstellen Sie DM, indem Sie eine Verknüpfung mit dem Benutzer herstellen |
user.sent_dms.create!(receiver_id: other_user.id) | Erstellen Sie DM durch Verknüpfung mit dem Benutzer (Ausgabefehler bei Fehler) |
user.sent_dms.build(receiver_id: other_user.id) | Gibt ein neues DM-Objekt zurück, das dem Benutzer zugeordnet ist |
user.sent_dms.find_by(id:1) | Gibt DM mit der dem Benutzer zugeordneten ID 1 zurück |
Probieren Sie es auf der Konsole aus. Mach dm1.
>> user1 = User.first
>> user2 = User.second
>> dm1 = user1.sent_dms.create(receiver_id: user2.id, content: "hoge dm1")
Das Benutzerobjekt von Absender und Empfänger wurde zurückgegeben.
>> dm1.sender
=> #<User id: 1, name: "Example User", email: "[email protected]", created_at: "2020-10-26 01:37:04", updated_at: "2020-10-26 01:37:04", password_digest: "$2a$10$2TZtcwmSTCfl9Bigz2nYGO8U1YA8ksfNXUr2O/fSGOY...", remember_digest: nil, admin: true, activation_digest: "$2a$10$EaQUKa6hfGEHosjnICR4VuYMxfOxunTOsPGQYUimNLn...", activated: true, activated_at: "2020-10-26 01:37:03", reset_digest: nil, reset_sent_at: nil, unique_name: "Example">
>> dm1.receiver
=> #<User id: 2, name: "Van Zemlak", email: "[email protected]", created_at: "2020-10-26 01:37:04", updated_at: "2020-10-26 01:37:04", password_digest: "$2a$10$H22BJeNVA3hYdEw/a5RArekRy73q/0AtvidwRiVpoUK...", remember_digest: nil, admin: false, activation_digest: "$2a$10$xm7AJE4Q3fzq3gi5tmVnyeld8wahxMHN/dE2Sn2jSUW...", activated: true, activated_at: "2020-10-26 01:37:04", reset_digest: nil, reset_sent_at: nil, unique_name: "Craig1">
Durchsuchen Sie die Liste der DMs des Benutzers und suchen Sie nach dm anhand der ID.
>> user1.sent_dms
Dm Load (0.2ms) SELECT "dms".* FROM "dms" WHERE "dms"."sender_id" = ? LIMIT ? [["sender_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Dm id: 2, content: "hogehoge", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-02 02:27:35", updated_at: "2020-11-02 02:27:35">, #<Dm id: 3, content: "hoge dm1", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-03 00:21:40", updated_at: "2020-11-03 00:21:40">]>
>> user1.sent_dms.find_by(receiver_id: 2)
Dm Load (0.4ms) SELECT "dms".* FROM "dms" WHERE "dms"."sender_id" = ? AND "dms"."receiver_id" = ? LIMIT ? [["sender_id", 1], ["receiver_id", 2], ["LIMIT", 1]]
=> #<Dm id: 2, content: "hogehoge", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-02 02:27:35", updated_at: "2020-11-02 02:27:35">
Ich benötige eine Liste von DMs für den Empfänger. Lesen Sie das Tutorial, da das folgende die gleiche Struktur hat. Die Methode ist wahrscheinlich, versuchen Sie es also auf der Konsole.
>> user2.received_dms
Dm Load (0.1ms) SELECT "dms".* FROM "dms" WHERE "dms"."receiver_id" = ? LIMIT ? [["receiver_id", 2], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Dm id: 2, content: "hogehoge", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-02 02:27:35", updated_at: "2020-11-02 02:27:35">, #<Dm id: 3, content: "hoge dm1", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-03 00:21:40", updated_at: "2020-11-03 00:21:40">]>
Ich habe ein Modell, aber ich frage mich, ob ich alle Methoden habe, die ich für meine Anforderungen benötige.
Überprüfen Sie den Twitter-Bildschirm erneut. Der DM-Bildschirm hat eine Eltern-Kind-Struktur, und der übergeordnete Bildschirm ist eine Liste von Benutzern, die in der Vergangenheit miteinander interagiert haben. Wenn Sie einen Benutzer auswählen, wird in diesem Bildschirm der DM-Austausch aufgelistet.
Eine erforderliche Methode gibt eine Liste von Benutzern zurück, mit denen Sie in der Vergangenheit interagiert haben. Als ich im Internet nach find suchte, stellte ich fest, dass die OR-Bedingung wo verwendet werden kann. https://qiita.com/nakayuu07/items/3d5e2f8784b6f18186f2 Probieren Sie es auf der Konsole aus.
>> Dm.where(sender_id: 1).or(Dm.where(receiver_id: 1))
Dm Load (0.1ms) SELECT "dms".* FROM "dms" WHERE ("dms"."sender_id" = ? OR "dms"."receiver_id" = ?) LIMIT ? [["sender_id", 1], ["receiver_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Dm id: 2, content: "hogehoge", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-02 02:27:35", updated_at: "2020-11-02 02:27:35">, #<Dm id: 3, content: "hoge dm1", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-03 00:21:40", updated_at: "2020-11-03 00:21:40">]>
>> Dm.where(sender_id: 2).or(Dm.where(receiver_id: 2))
Dm Load (0.1ms) SELECT "dms".* FROM "dms" WHERE ("dms"."sender_id" = ? OR "dms"."receiver_id" = ?) LIMIT ? [["sender_id", 2], ["receiver_id", 2], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Dm id: 2, content: "hogehoge", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-02 02:27:35", updated_at: "2020-11-02 02:27:35">, #<Dm id: 3, content: "hoge dm1", sender_id: 1, receiver_id: 2, deleted: false, created_at: "2020-11-03 00:21:40", updated_at: "2020-11-03 00:21:40">]>
Diese Suche erlaubt nicht die Funktion der übergeordneten und untergeordneten Bildschirme. Alle DMs aller Gegner sind gemischt. Zu diesem Zeitpunkt stellte sich heraus, dass die Spezifikationen nicht vollständig untersucht wurden. Die Funktion zum Erstellen eines Bildschirms für jeden DM-Partner wird hochgestuft, wenn er später erstellt werden kann.
Machen Sie einen Test des Modells. Führen Sie eine DM-Validierung unter Bezugnahme auf Micropost durch. Lesen Sie 13.1.2 "Micropost Validation" im Tutorial. Die DM-Datei des Geräts ist ein Beispiel. Löschen Sie sie daher.
test/models/dm_test.rb
class DmTest < ActiveSupport::TestCase
def setup
@sender = users(:michael)
@receiver = users(:archer)
@dm = Dm.new(content: "hogehoge1", sender_id: @sender.id, receiver_id: @receiver.id)
end
test "should be valid" do
assert @dm.valid?
end
test "sender should be present" do
@dm.sender_id = nil
assert_not @dm.valid?
end
test "receiver should be present" do
@dm.receiver_id = nil
assert_not @dm.valid?
end
test "contentr should be present" do
@dm.content = nil
assert_not @dm.valid?
end
test "contentr should be at most 140 characters" do
@dm.content = "a" * 141
assert_not @dm.valid?
end
end
Fügen Sie eine Validierung für Micropost hinzu. Der Test ist jetzt GRÜN.
app/models/dm.rb
class Dm < ApplicationRecord
belongs_to :sender, class_name: "User"
belongs_to :receiver, class_name: "User"
validates :content, presence: true, length: { maximum: 140 }
end
Ändern Sie die Methode beim Erstellen eines DM auf die normalerweise korrekte Weise.
test/models/dm_test.rb
def setup
@dm = @sender.sent_dms.build(content: "hogehoge1", receiver_id: @receiver.id)
end
Lässt DMs in chronologischer Reihenfolge zurückkehren. Lesen Sie 13.1.4 "Verbesserung der Mikropost". Schreiben Sie zuerst den Test.
test/models/dm_test.rb
class DmTest < ActiveSupport::TestCase
...
test "order should be most recent first" do
assert_equal sent_dms(:most_recent), Dm.first
end
end
Erstellen Sie Eltern-Kind-Beziehungsdaten im Fixture. https://qiita.com/seimiyajun/items/ffefdfc74b9fce76a538 Ich bezog mich auf.
test/fixtures/dms.yml
morning:
content: "Good morning!"
sender: michael
receiver: archer
created_at: <%= 10.minutes.ago %>
Stellen Sie so ein, dass sie in der Reihenfolge von created_at angeordnet sind. Der Test ist jetzt GRÜN.
app/models/dm.rb
class Dm < ApplicationRecord
belongs_to :sender, class_name: "User"
belongs_to :receiver, class_name: "User"
default_scope -> { order(created_at: :desc) }
validates :content, presence: true, length: { maximum: 140 }
end
Denken Sie darüber nach hinzuzufügen: zerstören. Wenn der Benutzer gelöscht wurde, wurde entschieden, dass der vergangene DM erhalten bleibt. Fügen Sie diesen Test hinzu. Siehe Listing 13.20.
test/models/user_test.rb GREEN
test "associated dms should not be destroyed" do
@user.save
@user.sent_dms.create!(content: "Lorem ipsum", receiver_id: users(:archer).id)
assert_no_difference 'Dm.count' do
@user.destroy
end
end
end
Das Modell wurde bisher fertiggestellt.
8,5 Stunden vom 31.10. Bis 06.11.