[JAVA] [Rails] Implémentation asynchrone de la fonction similaire

1.Tout d'abord

Comme le montre la vidéo de démonstration ci-dessous, nous mettrons en œuvre une fonction qui vous permet «d'aimer» le contenu publié par l'utilisateur. Image from Gyazo

2. Prérequis

En supposant que la fonction d'enregistrement de l'utilisateur et la fonction de publication ont déjà été implémentées, ajoutez-y la "fonction similaire". Je vais continuer avec le flux.

Je pense que ce sera plus facile à comprendre si vous pouvez imaginer la structure de la base de données comme indiqué ci-dessous. ER 図(Qiita).png

3. Mise en œuvre d'une fonction similaire

** ■ Flux jusqu'à la mise en œuvre **

En gros, nous allons l'implémenter dans le flux suivant. ・ Création d'un modèle    ↓ ・ Ajout de routage    ↓ ・ Création d'un contrôleur    ↓ -Créer une vue

Eh bien, allons vite.

3-1. Créer un modèle similaire

Commencez par créer un modèle Like. Exécutez la commande suivante dans le terminal.

Terminal


$ rails g model Like

Un nouveau fichier de migration sera créé, modifiez-le comme suit.

db>migrate>xxxxxx_create_likes.rb


class CreateLikes < ActiveRecord::Migration[6.0]
  def change
    create_table :likes do |t|
      # ===Partie Postscript===
      t.references :tweet, foreign_key: true, null: false
      t.references :user, foreign_key: true, null: false
      # ===Partie Postscript===
      t.timestamps
    end
  end
end

Si vous enregistrez comme type de références comme ci-dessus, vous pouvez spécifier `` tweet_id``` et `ʻuser_id``` comme clés externes. Maintenant, exécutons le fichier de migration et créons une table des likes.

Terminal


$ rails db:migrate

Après avoir exécuté la commande ci-dessus, vérifiez si la table des likes a été créée. Après avoir confirmé qu'il a été créé avec succès, l'étape suivante consiste à configurer l'association.

3-2. Paramètres d'association

Une association est une association entre deux modèles. Nous définirons les associations pour le modèle User et le modèle Like, ainsi que le modèle Tweet et le modèle Like.

Paramètres d'association du modèle utilisateur et du modèle similaire

Commencez par configurer l'association entre le modèle User et le modèle Like.

La relation entre les deux modèles est la suivante. ・ Les utilisateurs peuvent aimer plusieurs fois ・ Il n'y a qu'un seul utilisateur qui aime A

En d'autres termes, le modèle User et le modèle Like ont une relation «un à plusieurs». Maintenant, écrivons le code.

Ajoutez le code ci-dessous au modèle utilisateur.

app>models>user.rb


class User < ApplicationRecord

  has_many :tweets, dependent: :destroy

  #Ajouter cette ligne
  has_many :likes

end

has_manyIndique qu'il existe une relation «un à plusieurs» avec d'autres modèles.

Ensuite, ajoutez le code ci-dessous au modèle Like.

app>models>like.rb


class Like < ApplicationRecord

  #Ajouter cette ligne
  belongs_to :user

end

belongs_toEsthas_manyÀ l'opposé, cela montre qu'il existe une relation «plusieurs à un» avec d'autres modèles.

Vous avez maintenant configuré une association entre le modèle User et le modèle Like.

Paramètres d'association du modèle Tweet et du modèle J'aime

De la même manière, configurez l'association entre le modèle Tweet et le modèle Like.

La relation entre les deux modèles est la suivante. ・ Plusieurs likes sont attribués à un message ・ Il n'y a qu'un seul article lié à Like A

En d'autres termes, le modèle Tweet et le modèle Like ont également une relation «un-à-plusieurs». Maintenant, écrivons le code.

Veuillez ajouter le code comme suit au modèle de Tweet.

app>models>tweet.rb


class Tweet < ApplicationRecord
  belongs_to :user

  #Ajouter cette ligne
  has_many :likes, dependent: :destroy

end

dependent: :En ajoutant destroy, lorsqu'un message est supprimé, les likes associés à ce message seront également supprimés.



 Vient ensuite le modèle Like.


#### **`app>models>like.rb`**
```ruby

class Like < ApplicationRecord

  belongs_to :user

  #Ajouter cette ligne
  belongs_to :tweet

end

Ceci termine les paramètres d'association pour tous les modèles.

3-3. Paramètres de validation

Puisque nous voulons qu'un utilisateur n'aime qu'une seule fois le message A, définissez la validation de sorte qu'il ne puisse pas être pressé plus d'une fois.

Veuillez ajouter ce qui suit au modèle Like.

app>models>like.rb


class Like < ApplicationRecord

  belongs_to :user
  belongs_to :tweet

  #Ajouter cette ligne
  validates :user_id, uniqueness: { scope: :tweet_id }

end

En écrivant comme ci-dessus, vous pouvez empêcher user_id et `` `tweet_id``` de se chevaucher. Ceci termine les paramètres de validation.

3-4. Ajout de routage

Enfin, nous mettrons en œuvre la fonction similaire pour de bon.

Tout d'abord, ajoutons le routage utilisé pour la fonction similaire. Veuillez ajouter le code comme suit.

config>routes.rb


Rails.application.routes.draw do
  devise_for :users,
    controllers: { registrations: 'registrations' }

  resources :tweets, only: [:index, :new, :create, :show, :destroy] do

    #Ajouter cette ligne
    resources :likes, only: [:create, :destroy]

  end

end

J'ai défini les actions créer '' et détruire '' du contrôleur des likes car je dois ajouter une route pour enregistrer et supprimer des informations similaires.

En imbriquant le routage, vous pouvez clairement indiquer à quel poste le similaire est associé.

Après avoir ajouté le code, assurez-vous d'utiliser la commande `` rails routes '' pour vous assurer que les paramètres de routage sont corrects.

3-5. Création d'un contrôleur de likes

Ensuite, nous allons créer un contrôleur de likes. Exécutez la commande suivante dans le terminal.

Terminal


$ rails g controller likes

Vous pouvez créer un contrôleur de likes en exécutant la commande ci-dessus.

Créons maintenant une action créer '' et une action détruire '' dans le contrôleur likes créé. Veuillez ajouter le code comme suit.

app>controllers>likes_controller.rb


class LikesController < ApplicationController

  # ===Partie Postscript===
  def create
    @like = current_user.likes.build(like_params)
    @tweet = @like.tweet
    if @like.save
      respond_to :js
    end
  end

  def destroy
    @like = Like.find_by(id: params[:id])
    @tweet = @like.tweet
    if @like.destroy
      respond_to :js
    end
  end

  private
    def like_params
      params.permit(:tweet_id)
    end
  # ===Partie Postscript===

end

En supposant que vous compreniez les méthodes et paramètres privés, jetons un bref coup d'œil au code ajouté.

créer une action

Premièrement, `@ like``` contient le` `ʻuser_id``` de l'utilisateur qui a" aimé "le message et le` tweet_id``` du message "aimé". Je vais. Ce code utilise la méthode de construction pour créer une instance.

Ensuite, @ tweet contient les informations du post associé à `` `` @ like, c'est-à-dire les informations du post "aimé". @tweetÀ quel poste"Comme c'est gentil"Utilisé là où vous créez la vue pour déterminer si vous avez appuyé sur.

La dernière partie if @ like.save change le format de la réponse renvoyée lorsque "Like" est pressé avec la méthode `` `respond_to```. Afin de refléter la vue en temps réel lorsque vous appuyez sur "J'aime", la réponse est renvoyée au format JS.

détruire l'action

Il y a de nombreuses parties qui chevauchent le contenu expliqué dans l'action de création, donc pour expliquer brièvement, id est déterminé à partir de la requête HTTP reçue, et l'enregistrement spécifié dans `` `@ like``` Contient des informations.

Encore une fois, afin de refléter la vue en temps réel, la réponse est renvoyée au format JS.

3-5. Créer une vue

Il est enfin temps de créer une vue.

Tout d'abord, éditons l'écran de visualisation de la liste des articles ... Je voudrais dire, mais définissons d'abord la méthode à utiliser dans la vue.

Veuillez ajouter le code comme suit au modèle de Tweet.

app>models>tweet.rb


class Tweet < ApplicationRecord
  belongs_to :user
  has_many :likes, dependent: :destroy

  #Partie supplémentaire(liked_par méthode)
  def liked_by(user)
    Like.find_by(user_id: user.id, tweet_id: id)
  end
  #Partie supplémentaire

end

La méthode liké_parajoutée ci-dessus recherche une correspondance entreuser_id et `` `tweet_id et renvoie nill si elle n'existe pas.

Ensuite, ajoutez le code suivant à app / views / tweets / index.html.erb.

html:app>views>tweets>index.html.erb



<% @tweets.each do |tweet| %>

  #Ajouter à la partie où vous souhaitez afficher le bouton J'aime
  <div class="content-like">
    <ul class="content-like__icons">
      <li id="<%= tweet.id.to_s %>">
        <% if tweet.liked_by(current_user).present? %>
          <%= link_to (tweet_like_path(tweet.id, tweet.liked_by(current_user)), method: :DELETE, remote: true, class: "liked") do %>
            <i class="far fa-thumbs-up"></i>
          <% end %>
        <% else %>
          <%= link_to (tweet_likes_path(tweet), method: :POST, remote: true, class: "like") do %>
            <i class="far fa-thumbs-up"></i>
          <% end %>
        <% end %>
      </li>
    </ul>
  </div>
  #C'est la fin de la partie supplémentaire

<% end %>

liked_byComme argument pourcurrent_user En passant, l'utilisateur actuellement connecté peut publier"Comme c'est gentil"Je juge si je le fais.

Maintenant, si vous cliquez sur le bouton "J'aime" alors que l'utilisateur n'est pas "J'aime", l'action créer``` que vous avez créée précédemment sera exécutée, et lorsque l'utilisateur est "J'aime", J'ai pu exécuter une action détruire '' et créer une branche conditionnelle.

N'oubliez pas d'ajouter l'option `remote: true``` à` link_to``` car vous devez appeler le fichier`` .js.erb``` lorsque le lien est enfoncé. S'il te plait donne moi.

Pour l'icône "Bouton J'aime", Font Awesome est utilisé. Pour la méthode d'introduction, je pense que l'article de qiita suivant, etc. sera utile. méthode d'installation des rails font-awesome-sass

Ensuite, créez un fichier à afficher lorsque l'action de création est exécutée.

app/Créez un dossier likes directement sous le dossier views et créez-y.js.Créez un fichier erb.



 Après avoir créé le fichier, ajoutez le code comme suit.


#### **`ruby:app>views>likes>create.js.erb`**

$('#<%= @tweet.id.to_s %>'). html('<%= j render "tweets/liked", { tweet: @tweet } %>');

 Le code ci-dessus appelle le fichier `` `` _liked.html.erb``` dans le dossier `` `` tweets``` lorsque l'action de création est exécutée.


#### **`Dans le dossier tweets_liked.html.Créez un fichier erb et ajoutez le code suivant.`**

html:app>views>tweets>_liked.html.erb


<%= link_to (tweet_like_path(tweet.id, tweet.liked_by(current_user)), method: :DELETE, remote: true, class: "liked") do %>
  <i class="far fa-thumbs-up"></i>
<% end %>

Dans le code ci-dessus, lorsque j'appuie sur le bouton "J'aime", le code HTML qui annule le "J'aime" s'affiche.

Dans le même flux, créons un fichier qui sera appelé lorsque l'action de destruction est exécutée.

app/views>détruire dans le dossier likes.js.Créez un fichier erb.



 Après avoir créé le fichier, ajoutez le code comme suit.


#### **`ruby:app>views>likes>destroy.js.erb`**

$('#<%= @tweet.id.to_s %>'). html('<%= j render "tweets/like", { tweet: @tweet } %>');



#### **`Dans le dossier tweets_like.html.Créez un fichier erb et ajoutez le code suivant.`**

html:app>views>tweets>_like.html.erb


<%= link_to (tweet_likes_path(tweet), method: :POST, remote: true, class: "like") do %>
  <i class="far fa-thumbs-up"></i>
<% end %>

Avec ce qui précède, nous avons pu implémenter la fonction similaire de manière asynchrone.

Le reste est à quoi il ressemble, mais le nom de la classe est comme '' quand il est aimé, et comme '' quand il ne l'est pas, alors essayez de le personnaliser avec CSS. S'il te plait donne moi.

Dans mon cas, je change la couleur de l'icône en rouge quand elle est aimée et en gris quand elle ne l'est pas.

app>assets>stylesheets>tweets>_tweet.css


.like {
  color: gray;
}

.liked {
  color: red;
}

4. Enfin

C'est mon premier article, mais écrire un article est plus difficile que je ne l'avais imaginé. Je vous serais reconnaissant de bien vouloir signaler les parties difficiles à comprendre ou incorrectes.

Merci d'avoir lu jusqu'au bout ☺️

Recommended Posts

[Rails] Implémentation asynchrone de la fonction similaire
[Rails] Implémentation d'une fonction similaire
[Rails] À propos de la mise en œuvre de la fonction similaire
[Ruby on rails] Implémentation d'une fonction similaire
Implémentation d'une fonction similaire (Ajax)
[Rails] Implémentation de la fonction de catégorie
[Rails] Implémentation de la fonction tutoriel
[Rails] Implémentation de la fonction d'importation CSV
[Rails] Implémentation de la fonction de prévisualisation d'image
[Rails] Implémentation de la fonction de retrait utilisateur
[Rails] Implémentation de la fonction d'exportation CSV
Implémentation d'une fonction similaire en Java
Mise en place de la fonction de tri des rails (affichés par ordre de nombre de like)
Rails [Pour les débutants] Implémentation de la fonction de commentaire
Implémentation de la fonction de recherche
Mise en œuvre de la fonction de pagénation
[Rails] [jQuery] Implémentation de fonction asynchrone avec remote: true et js.erb
Implémentation de la fonction de connexion Ruby on Rails (Session)
[Rails] Implémentation de la fonction d'agrandissement d'image à l'aide de lightbox2
Implémentation de la fonction de recherche floue Rails
Implémentation de la fonction de recherche séquentielle
Implémentation de la fonction de prévisualisation d'image
Mise en œuvre de la fonction déroulante de catégorie
[Ruby on Rails] Communication asynchrone de la fonction de publication, ajax
[Rails] Implémentation de la fonction glisser-déposer (avec effet)
Implémentation de la fonction de connexion Ruby on Rails (édition de devise)
[Rails] Implémentation de la fonction de catégorie multicouche en utilisant l'ascendance "Préparation"
[Rails] Implémentation de la fonction de catégorie multicouche à l'aide de l'ascendance "seed edition"
[Rails] Implémentation de la suppression logique utilisateur
[Rails] Implémentation de la fonction de catégorie multicouche en utilisant l'ascendance "Edit Form Edition"
[Rails] Implémentation de la fonction de catégorie multicouche à l'aide de l'ascendance "Formulaire de création"
Implémentation du traitement asynchrone dans Tomcat
[Rails] Implémentation de fonctions de catégorie plusieurs à plusieurs
[Rails] Implémentation de la fonction de catégorie d'ascendance gemme
[Ruby on Rails] Implémentation de la fonction de commentaire
[Rails] Commentaire mémo de procédure d'implémentation
[Rails] Implémentation d'une nouvelle fonction d'enregistrement au format assistant à l'aide de devise
J'ai essayé d'implémenter le traitement Ajax de la fonction similaire dans Rails
[Rails] Implémentation de la fonction coupon (avec fonction de suppression automatique par traitement par lots)
[Rails] Implémentation de la fonction de balise à l'aide de la fonction agit-as-taggable-on et de la fonction de complétion d'entrée de balise à l'aide de tag-it
[Rails] Ajout de la fonction de commentaire Ruby On Rails
Implémentation de la fonction d'authentification des utilisateurs à l'aide de devise (2)
Rails Ajout d'une fonction de connexion facile et facile
Implémentation du traitement asynchrone compatible multi-tenant dans Tomcat