[RUBY] [Rails] J'ai implémenté le message d'erreur de validation avec une communication asynchrone!

Je suis un débutant avec "super" qui se débat tous les jours avec les Rails. Partagez pour organiser vos propres connaissances.

introduction

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!

Validation

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!

Contrôleur des commentaires

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!

Contrôleur de livres

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!

Livres afficher la page

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.

Partie partielle du message d'erreur

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.

Fichier js utilisé pour la communication asynchrone des messages d'erreur

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é! !!

(Supplément) Le fichier js de la fonction de commentaire elle-même est également décrit.

ruby:app/views/comments/create.js.erb


$(".comments").html("<%= j(render 'comments/index', book: @book) %>");
$("#comment_comment").val("");

Image d'écran

En implémentant une communication asynchrone image.png Si vous essayez d'envoyer un commentaire avec «vide» tel quel, image.png 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é.

en conclusion

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

[Rails] J'ai implémenté le message d'erreur de validation avec une communication asynchrone!
Fonction de publication implémentée par communication asynchrone dans Rails
J'ai essayé d'implémenter la fonction similaire par communication asynchrone
[Rails] Traduisons le message d'erreur en japonais
Rails ~ Comprendre la fonction de message ~
[Java] J'ai essayé d'implémenter la combinaison.
J'ai essayé de traduire le message d'erreur lors de l'exécution d'Eclipse (Java)
J'ai essayé d'implémenter l'API Rails avec TDD par RSpec. part2 -authentification de l'utilisateur-
Je veux contrôler le message d'erreur par défaut de Spring Boot
J'ai essayé d'implémenter l'API Rails avec TDD par RSpec. part3-Implémentation d'action avec authentification-
Je ne vois pas d'erreur dans l'installation du bundle Rails ... la solution
[Rails] Erreur de validation inattendue dans l'appareil
[Rails] J'ai essayé de supprimer l'application
J'ai essayé de connecter le compteur de points à la plate-forme MZ par communication série
J'ai essayé d'implémenter l'API Rails avec TDD par RSpec. part1-Implémentation de l'action sans authentification-
Je souhaite afficher un message d'erreur lors de l'inscription dans la base de données
Communication asynchrone dans le champ de commentaire interactif
Obtenez un message d'erreur en utilisant n'importe quelle méthode?
Mettre en œuvre une validation personnalisée avec des annotations dans Spring Framework et générer un message
[Ruby on Rails] Comment japonaisiser le message d'erreur de l'objet Form (ActiveModel)