J'écrirai la procédure pour implémenter la fonction suivante en utilisant form_with!
Nous implémenterons les fonctions suivantes __1. Possibilité de suivre / ne plus suivre les utilisateurs __ __2. Suivez la fonction d'affichage de la liste des utilisateurs / abonnés __
Je me suis référé à l'article Comment faire une fonction de suivi avec Rails, et surtout pour une explication détaillée de l'association liée à la fonction de suivi, cet article est très utile. devenu!
environnement ・ Rails 5.2.4.2 ・ Rubis 2.6.5 · Svelte · Concevoir
__ De plus, on suppose que les fonctions utilisateur sont implémentées. __
__ Comment configurer une application Rails dans l'environnement ci-dessus __
__ ↓ Cela ressemblera à ceci après la mise en œuvre. (Je suis désolé, ça a l'air simple ...) ↓ __
$ rails g model Relationship user:references follow:references
__ · La table des relations
créée ici est une table intermédiaire pour les utilisateurs à suivre et les utilisateurs à suivre. __
La table intermédiaire reconnaît __ ・ ʻusercomme modèle d'utilisateur suiveur et
follow` comme modèle d'utilisateur suiveur. __
db/migrate/[timestamps]_create_relationships.rb
class CreateRelationships < ActiveRecord::Migration[5.2]
def change
create_table :relationships do |t|
t.references :user, foreign_key: true
t.references :follow, foreign_key: { to_table: :users }
t.timestamps
t.index [:user_id, :follow_id], unique: true
end
end
end
La raison pour laquelle les modèles référencés sont séparés par __ · utilisateur et suit est que «l'utilisateur suivant» et «l'utilisateur suivi» doivent être considérés comme des modèles séparés. __
__ · t.references: user, Foreign_key: true
__: __user La clé externe du modèle est définie. __
__ · t.references: follow, clé_tranger: {to_table :: users}
__: __follow La clé externe du modèle est définie. Le modèle suivant est un nom de modèle fictif qui n'existe pas, et je le crée en ce moment. Par conséquent, en définissant {to_table :: users}, le modèle de la source de référence est enseigné. __
__ ・ t.index [: user_id ,: follow_id], unique: true
__: En donnant l'unicité à la combinaison de __user_id et follow_id, la duplication des données est empêchée, c'est-à-dire que le même utilisateur est suivi deux fois. Est prévenu. __
$ rails db:migrate
app/models/relationship.rb
class Relationship < ApplicationRecord
belongs_to :user
belongs_to :follow, class_name: "User"
validates :user_id, presence: true
validates :follow_id, presence: true
end
__ · appartient_à: utilisateur
__: __ C'est l'association habituelle. __
__ · appartient à: follow, nom_classe:" User "
__: __ Il est décrit qu'il appartient à la classe suivante, mais comme mentionné ci-dessus, follow est une classe fictive, alors faites-y référence par nom_classe:" Utilisateur "
Je vais vous dire le modèle d'origine. __
app/models/user.rb
class User < ApplicationRecord
#==============Association avec les utilisateurs suivis par un utilisateur=================
has_many :relationships, foreign_key: "user_id",
dependent: :destroy
has_many :followings, through: :relationships, source: :follow
#==========================================================================
#==============Association avec des utilisateurs qui suivent un utilisateur================
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "follow_id",
dependent: :destroy
has_many :followers, through: :passive_relationships, source: :user
#===========================================================================
end
__ · Le fichier de modèle de relation ci-dessus décrit les «associations permettant à un utilisateur d'accéder à un utilisateur suivi» et les «associations permettant à un utilisateur d'accéder à un utilisateur suivi». En d'autres termes, les détails seront décrits plus loin sur la figure. __
__ · has_many: relations, Foreign_key:" user_id ", depend :: destroy
__: __ Ceci déclare une association` qui permet à un utilisateur d'accéder à la clé externe user_id des relations de table intermédiaires. Je suis. __
__ Je pense que c'est facile à comprendre si vous l'imaginez comme suit! __
![Capture d'écran 2020-06-27 13.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606750/8a356efb-abfc-dbfa-60ce -9aca47c5c2d3.png)
__ · has_many: followings, through :: relations, source :: follow
__: __ Ceci déclare une association qui permet à un utilisateur d'accéder au modèle suivant via le follow_id dans les relations de table intermédiaires. Je vais. __
__ L'image ressemble à ceci! __
![Capture d'écran 2020-06-27 13.57.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606750/1dc2397f-2f50-7056-5dde -32cda530340c.png)
__ ・ Avec les deux lignes ci-dessus, vous pouvez obtenir les utilisateurs que l'utilisateur suit en définissant ʻUser.followings`. Une fois que cela est disponible, vous pouvez facilement afficher une liste d'abonnés d'un certain utilisateur. __
__ · has_many: passives_relationships, class_name:" Relationship ", Foreign_key:" follow_id ", depend :: destroy
__: __ Ceci déclare une association qui permet à un utilisateur d'accéder au follow_id de passives_relationships. Je suis.
Puisque passive_relationships est un modèle fictif que j'ai créé moi-même, j'enseigne le modèle référent en tant que nom_classe: "Relation". __
L'image est la suivante!
![Capture d'écran 2020-06-27 14.13.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606750/56cc736f-ccb5-6e43-3202 -1e57d223520a.png)
__ · has_many: followers, through :: passive_relationships, source :: user
__: __ Ceci déclare une association qui permet à un utilisateur d'accéder à des followers via le user_id de passive_relationships. __
L'image est la suivante!
![Capture d'écran 2020-06-27 14.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606750/6258ee85-2d12-5a92-66a2 -3f5281d57f3b.png)
__ ・ À partir des deux lignes ci-dessus, si vous utilisez User.followers, vous pouvez obtenir les utilisateurs qui suivent User. Avec cela, vous pouvez facilement afficher une liste d'utilisateurs qui suivent un certain utilisateur! __
app/models/user.rb
class User < ApplicationRecord
.
.
.
#<Description relative à l'association omise>
.
.
.
def following?(other_user)
self.followings.include?(other_user)
end
def follow(other_user)
unless self == other_user
self.relationships.find_or_create_by(follow_id: other_user.id)
end
end
def unfollow(other_user)
relationship = self.relationships.find_by(follow_id: other_user.id)
relationship.destroy if relationship
end
end
-Vérifiez si l'utilisateur suit @user en définissant following? (Other_user)
: __ʻUser.followings.include? (@User)`. Lors de la mise en œuvre du bouton de suivi, il est utilisé pour choisir de manière conditionnelle d'afficher le bouton à suivre ou le bouton de ne plus suivre. __
-En définissant follow (autre_utilisateur)
: __ʻUser.follow (@user), vous pouvez suivre @user. ʻSauf self == other_user
pour vous empêcher de vous suivre. J'utilise find_or_create_by pour faire référence à l'enregistrement d'identifiant de @user s'il existe, et le créer s'il n'existe pas. __
-En définissant __ʻunfollow (autre_utilisateur) __: __ ʻUser.unfollow (@user)
, vous pouvez ne plus suivre @user. __
-Maintenant que nous avons défini la méthode à suivre et ne plus suivre __user, l'étape suivante consiste à créer un contrôleur de relations et à implémenter la fonction pour accéder réellement à la base de données et suivre / ne plus suivre en utilisant ces méthodes. Je le ferai! __
$ rails g controller relationships
app/controllers/relationships_controller.rb
class RelationshipsController < ApplicationController
before_action :set_user
def create
following = current_user.follow(@user)
if following.save
flash[:success] = "Suivi de l'utilisateur"
redirect_to @user
else
flash.now[:alert] = "Impossible de suivre l'utilisateur"
redirect_to @user
end
end
def destroy
following = current_user.unfollow(@user)
if following.destroy
flash[:success] = "Utilisateur non suivi"
redirect_to @user
else
flash.now[:alert] = "Impossible de se désabonner de l'utilisateur"
redirect_to @user
end
end
private
def set_user
@user = User.find(params[:relationship][:follow_id])
end
end
-Dans le contrôleur __relationships, seule l'action de création qui suit l'utilisateur et l'action de destruction qui se désactive fonctionnent, donc n'écrivez que l'action de création et l'action de destruction. __ -Depuis le formulaire du bouton __` suivre / ne plus suivre, les données sont envoyées sous forme de paramètres [: relation] [: id_suivi], donc les données sont sous la forme de recherche (params [: relations] [: id_suivi]). Recevoir. __
-__ before_action: set_user
__: __ Puisque @user est toujours acquis dans chaque action, après avoir défini la méthode privée set_user, il est acquis à l'avance en utilisant before_action. __
-__ create action
__: __ L'utilisateur connecté (current_user) suit le @user acquis. J'utilise la méthode d'instance follow (other_user) définie dans le fichier de modèle utilisateur. __
· __destroy action
__: __ L'utilisateur connecté ne suit pas l'utilisateur acquis. J'utilise la méthode d'instance unfollow (other_user) définie dans le fichier de modèle utilisateur. __
・ __ La fonction pour accéder réellement à la base de données et suivre / ne plus suivre est terminée, nous allons donc implémenter le bouton `pour suivre / ne plus suivre '! __
__ ・ Commencez par créer un fichier relations / _follow_form.html.slim sous le répertoire app / views. __
ruby:app/views/relationships/_follow_form.html.slim
- unless current_user == user
#Bouton de désinscription
- if current_user.following?(user)
= form_with model: @relationship, url: relationship_path, method: :delete, local: true do |f|
= f.hidden_field :follow_id, value: user.id
= f.submit "Se désabonner"
#Bouton Suivre
- else
= form_with model: @set_relationship, url: relationships_path, local: true do |f|
= f.hidden_field :follow_id, value: user.id
= f.submit "Suivre"
__ · -à moins que l'utilisateur_actuel == utilisateur
__: __ L'affichage du bouton lui-même est commuté de sorte que vous ne pouvez pas vous suivre. L'utilisateur se réfère ici à @user que la vue qui place ce partiel obtient. __
__ · -if current_user.following? (User)
__: __ Vérifier si l'utilisateur connecté suit l'autre utilisateur. Si vous suivez, le bouton Ne plus suivre s'affiche et si vous ne le suivez pas, le bouton Suivre s'affiche. __
・= form_with model: @relationship, url: relationship_path, method: :delete, local: true do |f|
:Ceci est un bouton pour se désabonner.
__model: @ relation
@relationship est une variable d'instance qui obtient la relation entre l'utilisateur connecté et l'autre utilisateur. __
__ (Si vous placez ce formulaire de bouton de suivi dans app / views / users / show.html.slim, vous définirez la variable d'instance @relationship dans l'action show du fichier app / controllers / users_controller.rb.) __
__ʻUrl: chemin_relation` est le routage vers l'action de destruction du contrôleur de relations. Nous décrirons le routage plus tard. __
__method :: delete
spécifie la méthode DELETE dans la requête HTTP. __
Si __local: true
n'est pas ajouté, la spécification de soumission du formulaire sera Ajax et les données ne pourront pas être soumises, alors assurez-vous de la décrire dans form_with. __
__ ・ f.hidden_field: follow_id, value: user.id
__: Cette partie est facile à comprendre lorsque vous regardez réellement le code source terminé. __
![Capture d'écran 2020-06-27 15.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606750/6530abc7-b410-92c6-4f74 -3610f308bc01.png)
En spécifiant> __: follow_id
, les données seront envoyées sous la forme de paramètres [: relation] [: follow_id]. La partie définie par la méthode privée set_user du contrôleur de relations reçoit ces données. __
En spécifiant> __valeur: user.id
, l'id de l'autre utilisateur qui suit est stocké dans: follow_id et les données sont envoyées. __
・= form_with model: @set_relationship, url: relationships_path, local: true do |f|
:Ceci est un formulaire pour suivre l'autre utilisateur.
La variable d'instance @set_relationship de model: @ set_relationship
génère un modèle vide, et les données sont envoyées sous la forme de paramètres [: relation] [: follow_id] en référence à ce modèle vide. Faire cela.
__ʻUrl: relations_path` est le routage vers l'action de création du contrôleur de relations. Nous décrirons le routage plus tard. __
__ ・ = f.hidden_field: follow_id, value: user.id
: Vérifions le code source réellement complété. __
![Capture d'écran 2020-06-27 15.47.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606750/201d6a5e-3b2f-5e57-4155 -fd7326975490.png)
__ Identique au bouton de non-suivi, les données sont envoyées sous forme de paramètres [: relation] [: id_suivi]. __
__ ・ Maintenant que le bouton suivre / ne plus suivre a été créé, il est temps de définir le routage pour que ces données soient envoyées à l'action normalement! __
config/routes.rb
Rails.application.routes.draw do
.
.
#<Autre routage omis>
.
.
resources :relationships, only: [:create, :destroy]
Vérifiez les routes ajoutées avec la commande __ · $ rails routes | grep Relationship
. __
$ rails routes | grep relationship
relationships POST /relationships(.:format) relationships#create
relationship DELETE /relationships/:id(.:format) relationships#destroy
__ ・ Vous pouvez maintenant confirmer que vous pouvez suivre avec relations_path
/ unfollow avec relation_path
. __
__ ・ Je voudrais le placer dans le fichier app / views / users / show.html.slim au cas où vous voudriez pouvoir suivre ou ne plus suivre lorsque vous passez à la page de l'autre utilisateur. __
ruby:app/views/users/show.html.slim
Page de profil utilisateur h1
p
= "Nom: "
= @user.username
#================Ajouter un bouton de suivi=============================
= render 'relationships/follow_form', user: @user
#============================================================
p= link_to "Modifier le profil", edit_user_path(current_user)
__ · user: @user__: __ L'utilisateur décrit dans le partiel fait référence à @user défini dans l'action show. __
__- Le bouton a été placé, mais le bouton ne fonctionnera pas tel quel. En effet, comme mentionné précédemment, la variable d'instance @relationship et la variable d'instance @set_relationship doivent être définies dans l'action show. __
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
.
def show
@user = User.find(params[:id])
@relationship = current_user.relationships.find_by(follow_id: @user.id)
@set_relationship = current_user.relationships.new
end
.
.
.
end
__ · @ Relationship = current_user.relationships.find_by (follow_id: @ user.id)
__: __ Il s'agit de la variable d'instance référencée dans le formulaire de non-suivi. En récupérant ici les relations entre current_user et @user, vous pourrez envoyer des données comme les paramètres [: relation] [: follow_id] dans le form
. __
__ · @ set_relationship = current_user.relationships.new
__: __ Il s'agit de la variable d'instance référencée dans le formulaire à suivre. Je veux envoyer des données sous la forme de paramètres [: relation] [: follow_id], donc je crée une variable d'instance vide comme celle-ci. __
__ ・ Ceci termine l'implémentation de la fonction pour suivre / ne plus suivre les utilisateurs! Ensuite, nous allons implémenter une fonction pour afficher une liste d'utilisateurs qui nous suivent / utilisateurs qui nous suivent! __
__ · Ajouter un lien vers la page de la liste des abonnés / abonnés de l'utilisateur dans app / views / users / show.html.slim. __
ruby:app/views/users/show.html.slim
Page de profil utilisateur h1
p
= "Nom: "
= @user.username
#==============Lien vers la page de la liste des suiveurs / abonnés=================
= link_to "Suivre: #{@user.followings.count}", followings_user_path(@user.id)
= "/"
= link_to "Disciple: #{@user.followers.count}", followers_user_path(@user.id)
#============================================================
= render 'relationships/follow_form', user: @user
p= link_to "Modifier le profil", edit_user_path(current_user)
__ · Pour accéder aux abonnés / suiveurs, utilisez les suivants / suiveurs définis précédemment dans le fichier de modèle utilisateur. __
__ · @ user.followings.count
__: __ Affiche le nombre d'utilisateurs que l'utilisateur suit. __
__ · followings_user_path (@ user.id)
__: __ Je veux spécifier le chemin où l'URL est ʻusers /: id / followings`, donc écrivez comme indiqué sur la gauche. J'écrirai le routage plus tard afin que vous puissiez spécifier ce type de chemin. __
__ ・ L'accès à la page de la liste des abonnés est décrit de la même manière que l'accès à la page de la liste des utilisateurs suivants. __
config/routes.rb
Rails.application.routes.draw do
.
.
.
resources :users do
get :followings, on: :member
get :followers, on: :member
end
.
.
.
end
__ ・ Après avoir écrit comme ci-dessus, vérifiez le routage avec la commande $ rails routes | grep follow
. __
$ rails routes | grep follow
followings_user GET /users/:id/followings(.:format) users#followings
followers_user GET /users/:id/followers(.:format) users#followers
__ ・ followings_user_path
passera à la page de la liste des utilisateurs suivants, et followers_user_path
passera à la page de la liste des abonnés, donc c'est OK. __
__ · Étant donné que l'action suivante et l'action Suiveurs sont imbriquées dans la ressource utilisateurs, définissez deux actions dans le contrôleur d'utilisateurs. __
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
.
def followings
@user = User.find(params[:id])
@users = @user.followings.all
end
def followers
@user = User.find(params[:id])
@users = @user.followers.all
end
.
.
.
__ · Dans l'action suivante, tous les utilisateurs suivis par @user sont acquis, et dans l'action Suiveurs, tous les abonnés de @user sont acquis. __
__ · Créez les fichiers followings.html.slim
et followers.html.slim
dans le répertoire app / views / users. __
ruby:app/views/users/followings.html.slim
h2 abonnés
- @users.each do |user|
hr
= "username: "
= link_to user.username, user_path(user.id)
ruby:app/views/users/followers.html.slim
h2 abonnés
- @users.each do |user|
hr
= "username: "
= link_to user.username, user_path(user.id)
__ ・ Ceci termine la création de la page de suivi des utilisateurs / listes d'utilisateurs! __
Comment créer une fonction de suivi avec Rails
Recommended Posts