J'ai créé une fonction de réponse pour l'extension Rails Tutorial (Partie 2): Changer de modèle

Ceci est une continuation de l'article précédent sur la création d'une fonction de réponse dans le chapitre 14 du didacticiel Rails.

Identifier ce qu'il faut faire dans le travail de codage

Je vais passer en revue le travail à faire et le laver. ・ Créez une branche avec git ・ Faire un test    model、integration

Ajouter une colonne au modèle

Recherchez du texte expliquant comment ajouter une colonne modèle. Vous pouvez voir qu'en 9.1.1 vous ajoutiez des colonnes avec migrate.

Réfléchissez à comment faire l'affichage par réponse dans le modèle. Regardons à nouveau les spécifications. @reply ne doit apparaître que dans le flux du destinataire et celui de l'expéditeur. Pensez-y en trois parties selon la personne qui l'affiche. 1 expéditeur, 2 destinataire, 3. Tiers (ni expéditeur ni destinataire)

1 expéditeur

Puisqu'il s'agit d'un micro-message que j'ai posté, il sera affiché même avec la fonction actuelle.

2 destinataires

Il existe deux possibilités: le destinataire suit l'expéditeur et le destinataire non. Si le destinataire suit l'expéditeur, il sera toujours visible dans la fonction actuelle. Si le destinataire ne suit pas l'expéditeur, il ne sera pas affiché avec la fonction actuelle. Vous pouvez voir que nous devons ajouter des fonctionnalités ici.

La fonction est d'afficher in_reply_to si vous êtes égal. J'ai pensé que je modifierais ce que renvoie la méthode user.micrposts, mais cela ne fonctionne pas. Je ne l'ai pas posté. Il ne sélectionne pas l'expéditeur et renvoie le micro-message de la personne. Peu importe qui a publié C'est une fonction pour afficher tous les micro-messages qui sont égaux à in_reply_to.

L'idée est que plus vous avez de micro-messages, plus le risque de problèmes de performances est élevé. Il semble nécessaire d'ajouter un index comme contre-mesure. Je comprends qu'il existe un risque de rechercher par clé alternative au lieu de rechercher par clé primaire.

Pour en revenir à la façon de le faire, cette méthode de mise en œuvre l'affichera, que vous suiviez ou non l'expéditeur, j'ai donc trouvé qu'il n'est pas nécessaire de séparer les cas.

Ensuite, réfléchissez à la méthode à laquelle ajouter la fonction. En regardant l'extrait 14.46, la méthode d'alimentation dans le modèle utilisateur semble bonne. Il semble que vous puissiez spécifier la condition avec où.

3 Tiers

Lorsqu'un tiers affiche l'écran de flux du destinataire, la réponse n'apparaît pas. Si vous créez une fonction avec les spécifications ci-dessus, elle sera affichée. Par conséquent, il est nécessaire d'ajouter une fonction qui n'est pas affichée. Si vous n'êtes pas égal à in_reply_to, vous pouvez le masquer. Au début, j'ai pensé que je devrais apporter des modifications à ce que la méthode user.micrposts renvoie. Comme je l'ai mentionné ci-dessus, j'ai trouvé que la méthode d'alimentation était bonne pour le destinataire, donc j'ai intuitivement senti que la même méthode était bonne.

Instruction SELECT conditionnelle

Relisez 14.3.2.

Dans le tableau des micro-messages, sélectionnez tous les micro-messages qui ont un identifiant qui correspond à l'utilisateur qu'un utilisateur (c'est-à-dire lui-même) suit.

Dans le tableau des micro-messages, sélectionnez toutes les réponses dont vous êtes le destinataire.

SELECT * FROM microposts
WHERE  user_id IN (<list of ids>) 
             OR user_id = <user id> 
             OR in_reply_to = <user id>

Je pense que cela devrait être fait.

Annonce 14.44

  def feed
    Micropost.where("user_id IN (?) OR user_id = ? OR in_reply_to = ?", following_ids, id,id)
  end

Cela semble bon.

Je juge que les spécifications ont été supprimées avec cela et décide de le faire.

Créer une succursale

Créez une branche comme d'habitude.

ubuntu:~/environment/sample_app (master) $ git checkout -b reply-micropost

Ajouter une colonne au modèle

Trouvez dans le texte comment ajouter des colonnes au modèle. 6.3.1 J'ajoutais une colonne avec "Mot de passe haché". Faites-le de la même manière.

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

Créer un test de modèle

Ensuite, créez un test de modèle. 13.1.2 Procédez de la même manière que la validation Micropost. Quant au modèle à tester, j'ai ajouté une colonne à micropost, donc je pense que c'est micropost.

Créez un micro-message de réponse basé sur l'expéditeur et le destinataire de la réponse.

Le test affiché sur l'écran d'alimentation lorsque vous répondez est le test d'intégration. Avant cela, réfléchissez à ce qu'il faut tester avec le test du modèle.

En tant que test de la fonction de la méthode ajoutée par réponse, il semble que la mise à jour et la suppression ne soient pas dans CRUD, vous devez donc créer et lire la réponse. Je vais l'essayer sur la console.

>> 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>]>

Si la méthode existante est suffisante, il semble que les tests ne soient pas nécessaires car le modèle n'ajoute pas de fonctions, mais je vais l'écrire pour le moment.

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

Créer un test d'intégration

Maintenant que nous avons testé le modèle, créons un test d'intégration. Le contenu du test consiste à créer une réponse et à l'afficher sur l'écran d'alimentation du destinataire.

Avant cela, réfléchissez à l'endroit où effectuer les modifications. J'ai pensé que je devais faire un test du résultat car j'apporterais des modifications au contrôleur.

Commençons par le test d'intégration. Vous recherchez un test qui semble utile, following_test.rb semble bon. De plus, le lieu de publication est copié en fonction de microposts_interface_test.rb.

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

changer de fil

Apportez des modifications au flux pour afficher une réponse.

Commencez par créer des données de test. Ajoutez des données à l'appareil.

test/fixtures/microposts.yml


tonton:
  content: "@reply malory tonton is the name of the panda."
  created_at: <%= Time.zone.now %>
  user: michael

Où tester le flux, mais je pense que c'est un test de modèle car il change pour le modèle utilisateur.

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

Changez le flux.

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 %>

D'autres tests échouent en raison d'un changement de flux

La modification du flux a provoqué l'échec d'autres tests. Voir le message d'erreur.

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

Je reçois un message d'erreur indiquant qu'il y a un problème avec les données de test. Je pense que la cause est que les données de test avec la dernière heure de publication ont été créées comme most_recent dans le montage, mais tonton avait une heure de publication plus récente. Il n'est pas nécessaire de mettre à jour l'heure d'affichage, donc corrigez l'heure d'affichage du tonton.

test/fixtures/microposts.yml avant le changement


tonton:
  content: "@reply malory tonton is the name of the panda."
  created_at: <%= Time.zone.now %>
  user: michael

test/fixtures/microposts.après avoir changé 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 %>

Il a été réparé en toute sécurité.

Afficher et confirmer à l'écran

Assurez-vous que le micro-message avec @reply est affiché sur la page. Créez des exemples de données en vous référant à l'extrait 13.25: «Ajout de micropostes à des échantillons de données».

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 )

Lorsque j'ai soulevé le serveur de rails et affiché l'écran, il a été confirmé que le micro-message de réponse était affiché.

Temps requis

7,0 heures du 10/2 au 10/10.

Recommended Posts

J'ai créé une fonction de réponse pour l'extension Rails Tutorial (Partie 2): Changer de modèle
J'ai créé une fonction de réponse pour l'extension Rails Tutorial (Partie 5):
J'ai créé une fonction de réponse pour l'extension Rails Tutorial (Partie 4): une fonction qui rend l'utilisateur unique
J'ai essayé de créer une fonction de message de l'extension Rails Tutorial (Partie 1): Créer un modèle
J'ai essayé de faire une fonction de réponse de l'extension Rails Tutorial (Partie 3): Correction d'un malentendu des spécifications
J'ai essayé de créer une fonction de message pour l'extension Rails Tutorial (Partie 2): Créer un écran à afficher
Tutoriel pour créer un blog avec Rails pour les débutants Partie 1
Tutoriel pour créer un blog avec Rails pour les débutants Partie 2
Tutoriel pour créer un blog avec Rails pour les débutants Partie 0
J'ai fait une simple fonction de recommandation.
J'ai créé un outil Diff pour les fichiers Java
J'ai créé une bibliothèque d'extension Ruby en C
J'ai créé un robot LINE avec Rails + heroku
J'ai fait un portfolio avec Ruby On Rails
J'ai créé une fonction pour enregistrer des images avec l'API dans Spring Framework. Partie 1 (édition API)
J'ai créé une image Docker pour la version japonaise de SDAPS
J'ai créé un outil de vérification pour le module de version
J'ai fait une méthode pour demander la prime vendredi
Je souhaite définir une fonction dans la console Rails
J'ai créé une bibliothèque pour afficher des tutoriels sur Android.
J'ai créé une fonction pour enregistrer des images avec l'API dans Spring Framework. Partie 2 (édition client)
J'ai essayé de faire une version japonaise de la transmission automatique du courrier de Rails / devise
J'ai créé un environnement de développement avec rails6 + docker + postgreSQL + Materialise.
Je souhaite implémenter une fonction d'édition des informations produit ~ part1 ~
J'ai fait un majordome qui résume les tweets [Modèle de couverture maximale]
J'ai créé une application de chat.
[Rails] Implémentation de la fonction tutoriel
[Rails] J'ai créé une mini-application de calendrier simple avec des spécifications personnalisées.
Implémentez une fonction de recherche affinée pour plusieurs modèles sans gemme Rails5.
Je souhaite ajouter une fonction de navigation avec ruby on rails
J'ai posé une question qui peut être utilisée pour des entretiens techniques
Création d'une méthode pour demander Premium Friday (version Java 8)
J'ai essayé de créer une fonction de groupe (babillard) avec Rails