Je suis un débutant avec "super" qui se débat tous les jours avec les Rails. Partagez pour organiser vos propres connaissances.
L'autre jour, j'ai appris à implémenter la communication asynchrone dans Rails, mais il y avait une partie que je n'avais pas complètement digérée, donc je la sortirai pour approfondir ma compréhension! En supposant qu'un site publie des livres recommandés par les utilisateurs, vous pouvez commenter les livres publiés.
Cette fois, lorsque le bouton d'envoi est enfoncé avec le champ de commentaire vide, le message d'erreur apparaîtra directement au-dessus du champ de commentaire et le message d'erreur lui-même sera implémenté par une communication asynchrone. Allons vite!
models/comment.rb
class BookComment < ApplicationRecord
belongs_to :user #Lien vers le modèle utilisateur
belongs_to :book #Lié au modèle de livre
validates :body, presence: true, length: {maximum: 150}
end
En définissant presence: true
dans le modèle de commentaire, la publication dans le vide est interdite.
À propos, length: {maximum: 150}
est également défini.
Vérifions le contrôleur tout de suite!
comments_controller.rb
class BookCommentsController < ApplicationController
before_action :authenticate_user! #Autoriser l'accès uniquement aux utilisateurs connectés
def create
@book = Book.find(params[:book_id])
@comment = Comment.new(comment_params) #Le contrôle de validation est appliqué à ce moment!
@comment.book_id = @book.id
@comment.user_id = current_user.id
unless @comment.save #@Si le commentaire n'a pas pu être enregistré
render 'error' #comments/error.js.Appeler erb(Voir ci-dessous)
end
end
private
def comment_params
params.require(:comment).permit(:comment)
end
end
Les valeurs passées via les paramètres sont utilisées pour s'inscrire dans la base de données avec les méthodes new et save. À ce moment, les clés externes book_id et user_id ne peuvent pas être obtenues par paramètres, elles sont donc définies à ce moment. Eh bien, est-ce que tout va bien jusqu'à présent?
L'important ici est que le contrôle de validation soit effectué juste avant son enregistrement dans la base de données, donc la variable d'instance que vous obtenez dans l'instruction d'erreur est
@comment = Comment.new(comment_params)
Est-ce.
En d'autres termes, il vérifie si la valeur elle-même qui a passé le paramètre contient une erreur.
Ensuite, la section des commentaires se trouve sur la page de détails de Book, alors vérifions le contrôleur de Books!
books_controller.rb
class BookController < ApplicationController
before_action :authenticate_user! #Autoriser l'accès uniquement aux utilisateurs connectés
def show
@book = Book.find(params[:id])
@comment = Comment.new #Commentaires nouvelle méthode de transmission des valeurs au contrôleur
end
end
Il n'y aura pas de problème ici non plus! Vous avez atteint le tournant. Vérifions la page de détails de Book à ce rythme!
ruby:app/views/books/show.html.erb
<div id="comments_error">
<%= render 'layouts/errors', model: @comment %>
</div>
<%= form_with model:[@book,@comment] do |f| %>
<%= f.text_area :comment %>
<%= f.submit 'Envoyer'%>
<% end %>
Dans la partie de comments_error
de la première moitié, _errors.html.erb
des dispositions est appelée par render.
De plus, j'ai fourni un champ de saisie de commentaire en utilisant form_with
, mais je veux définir une communication asynchrone, donc je ne décrirai pas local: true
.
Dans le cas de form_with
, la communication asynchrone est utilisée par défaut, il n'est donc pas nécessaire d'écrire remote: true
.
ruby:app/views/layouts/_errors.html.erb
<% if model.errors.any? %>
<div id="error_explanation">
<h3>
<%= pluralize(obj.errors.count, "error") %> prohibited this model from being saved:
</h3>
<ul>
<% model.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
Vous souvenez-vous avoir appelé avec le rendu depuis la page Afficher de Livres?
Le message d'erreur est enfin là.
errors.full_messages
récupère tous les messages d'erreur dans un tableau.
Puisqu'il est supposé que nous sommes pris dans plusieurs erreurs, nous bouclons avec chaque méthode.
Étant donné que cette déclaration d'erreur est incluse par défaut, elle peut être utilisée dans diverses situations autres que la section des commentaires.
ruby:app/views/comments/error.js.erb
$("#comments_error").html("<%= j(render 'layouts/errors', model: @comment) %>");
Dans books / show.html.erb
, c'est le processus pour réécrire la partie de id =" comments_error "
.
Ciblant id =" comments_error "
avec $ (" # comments_error ")
, il est réécrit avec le contenu de layouts / _errors.html.erb
spécifié dans render'layouts / errors'
.
De plus, c'est «@ comment» passé au modèle ici, mais savez-vous où cela est défini?
Le fichier js a été appelé par le contrôleur Commentaires.
Autrement dit, défini dans l'action de création dans le contrôleur Commentaires,
@comment = Comment.new(comment_params)
Est passé à layouts / _errors.html.erb
.
Hmmm, c'est compliqué! !!
ruby:app/views/comments/create.js.erb
$(".comments").html("<%= j(render 'comments/index', book: @book) %>");
$("#comment_comment").val("");
En implémentant une communication asynchrone Si vous essayez d'envoyer un commentaire avec «vide» tel quel, J'étais en colère comme je m'y attendais. Ceci termine le message d'erreur en utilisant la communication asynchrone! Il est possible de convertir le texte du message en japonais, mais en raison du manque d'espace, c'est une autre opportunité.
La communication asynchrone a beaucoup de contrôleurs et de transitions de page à page, donc c'est très déroutant. Si vous le relisez plusieurs fois, je pense qu'il sera plus proche de votre compréhension. Si vous êtes en colère contre le flux de processus, vous pourrez peut-être raccourcir le temps de mise en œuvre. Pardon. Étudions ensemble et faisons de notre mieux!
Recommended Posts