Ruby 2.5.7 Rails 5.2.4
jQuery 1.12.4
Cette fois, je vais vous expliquer en utilisant la table Tag.
Tout d'abord, veuillez confirmer à l'avance que vous pouvez ajouter et supprimer des balises sans utiliser ajax.
Je ne parlerai pas de la localisation japonaise des messages d'erreur et des associations, donc si vous en avez besoin, faites-le vous-même.
turbolinks est désactivé. (Nous n'avons pas confirmé l'opération lorsqu'elle est activée.)
Comme le titre l'indique, nous utiliserons ajax pour ajouter / supprimer des balises et afficher des messages d'erreur dans les étapes suivantes.
views / layouts / _error_messages.html.erb
, views / layouts / _flash_messages.html.erb
, views / tags / _tag.html.erb
)En tant qu'image, lorsque vous appuyez sur le bouton d'envoi, l'action de création du contrôleur est exécutée.
La méthode qui appelle create.js.erb est exécutée dans l'action de création
JavaScript (jQuery) écrit dans create.js.erb se déclenche
La manipulation DOM écrase l'élément de message d'erreur et l'élément de liste de balises (méthode jQuery .html ()
)
La même chose s'applique à l'action de destruction lors de la suppression.
Comme le flux du formulaire rempli
Entrez une valeur dans le formulaire sur l'écran d'index. 1-1. Enregistrer une nouvelle balise si elle n’existe pas (message de réussite) 1-2. Si la balise existe, enregistrez l'échec (message d'erreur de validation) 1-3. Si ce champ est vide, l’enregistrement a échoué (message d’erreur de validation)
Supprimer des balises individuelles 1-1. Afficher le message de réussite
Comme tous sont ajax, la page entière ne sera pas mise à jour.
tag.rb
class Tag < ApplicationRecord
...
#Interdit les blancs et accorde l'unicité (dupliquer NG).
validates :name, presence: true, uniqueness: true
end
layouts / _error_messages.html.erb
, layouts / _flash_messages.html.erb
, _tag.html.erb
)Les trois modèles partiels créés ici sont écrasés par les opérations DOM en fonction de l'action.
Si vous écrivez dans jQuery, il sera redondant car vous ferez des opérations DOM ligne par ligne, utilisez donc des modèles partiels pour que jQuery décrit plus tard puisse être fait avec <% = render ...%>
1 ligne. Il est devenu.
Modèle partiel de message d'erreur de validation Si vous en avez déjà un, vous pouvez l'utiliser.
erb:layouts/_error_messages.html.erb
<% if model.errors.any? %>
<div id="validation-errors">
<p><%= model.errors.count %>Il y a des erreurs.</p>
<ul class="error-messages">
<% model.errors.full_messages.each do |message| %>
<li class="error-message"><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
S'il y a une erreur de validation lors de l'écrasement par la manipulation DOM de jQuery, un message d'erreur sera affiché. Remplacez la variable locale «model» par «@ tag» (Tag.new) dans index.html.erb, qui sera décrite plus tard.
Ensuite, un modèle partiel pour les messages de réussite (messages flash) Si vous l'avez déjà, veuillez l'utiliser.
erb:layouts/_flash_messages.html.erb
<% flash.each do |key, value| %>
<p class="alert alert-<%= key %>">
<%= value %>
</p>
<% end %>
Il est supposé obtenir du tableau avec chacun, mais ce n'est pas pour obtenir plusieurs messages flash, mais n'importe quelle touche (flash [key]
) peut être réaffiche avec cette phrase Je vais.
Il existe deux types de clés utilisées cette fois: [: success]
et [: warning]
. (Au fait, ces deux types sont également disponibles en bootstrap, j'ai donc choisi cette fois.)
Si vous utilisez ces deux éléments, vous pouvez réécrire le modèle partiel comme suit.
erb:layouts/_flash_messages.html.erb
<% case flash.keys[0] %>
<% when "success" %>
<p class="alert alert-<%= flash.keys[0] %>">
<%= flash[:success] %>
</p>
<% when "warning" %>
<p class="alert alert-<%= flash.keys[0] %>">
<%= flash[:warning] %>
</p>
<% end %>
Les clés stockées dans la mémoire flash sont des tableaux, elles doivent donc être clés [0]
.
Modifiez le message flash à afficher en fonction du modèle de touches dans l'instruction de cas.
La raison d'utiliser keys [0]
dans la classe de l'élément p est de changer la conception du css en fonction de la clé (succès ou avertissement dans ce cas).
Cependant, cela le rend redondant car il est nécessaire d'augmenter le nombre de lignes à chaque fois que le nombre de types de clés (les noms de clés peuvent être donnés arbitrairement) augmente.
Par conséquent, cette fois, en utilisant l'instruction each, le problème est éliminé. De plus, en en faisant un modèle partiel, il peut être réutilisé dans d'autres vues ainsi que dans le message d'erreur de validation.
Modèle partiel pour afficher la liste des balises ensuite
erb:tags/_tag.html.erb
<div class="tags-index__tags--tag">
<%= tag.name %>(<%= tag.menu_tag_ids.count %>)
<%= link_to 'X', tag_path(tag), method: :delete, remote: true %>
</div>
Si vous n'utilisez pas de modèle partiel, vous devez écrire 4 lignes avec jQuery, ce qui sera décrit plus tard, et je veux gérer les opérations DOM avec jQuery aussi simplement que possible, donc j'en ai fait un modèle partiel.
La variable locale «tag» est automatiquement remplacée en tant que variable locale individuelle «tag» dans le modèle partiel en spécifiant la variable d'instance «@ tags» (Tag.all) dans index.html.erb. (J'expliquerai en détail dans index.html.erb.)
(<% = tag.menu_tag_ids.count%>)
indique le nombre de menus pour lesquels la balise est utilisée à côté du nom de la balise. (Tableau de menu (omis) 1: Tableau d'étiquettes de menu multiple (tableau intermédiaire) (omis) Tableau d'étiquettes multiples: 1 (cette fois))
Pour <% = link_to'X ', tag_path (tag), method :: delete, remote: true%>
, appuyer sur X
déclenchera l'action de destruction. En définissant remote: true
, il est spécifié qu'il s'agit d'une communication ajax.
<détails> remote: true
(data-remote = "true" ʻattribute après la conversion html), seul le fichier JS est acquis. .. <br> Dans le cas de Rails, il y a une balise qui lit js dans la balise
` de layouts / application.html.erb, donc normalement lorsque HTML est acquis, js est également rechargé automatiquement. Cela ne s'applique pas si vous utilisez des turbolinks. </ datails>
Nous allons également créer un écran de liste de balises et un nouveau formulaire de saisie.
erb:views/tags/index.html.erb
<div class="contents tags-index">
<div class="tags-index--messages"><!--Zone d'affichage des messages--></div>
<h2>Liste de balises</h2>
<div class="tags-index__list" id="tags-index--tag-list">
<%= render @tags %>
</div>
<div class="tags-index__form">
<%= form_with model: @tag, url: tags_path(@tag) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
</div>
</div>
Le formulaire nouvellement ajouté est attaché au bas de la liste des balises.
Le nouveau formulaire d'inscription utilise form_with.
form_with est optional car la valeur par défaut a l'attribut remote: true
. (Si vous utilisez form_for, vous devez spécifier l'attribut remote: true
.)
Si vous n'utilisez pas ajax dans form_with, vous devez spécifier l'attribut local: true
.
L'assistant de formulaire indique à l'action uniquement JS si remote: true
et HTML si local: true
.
De plus, étant donné que la méthode HTTP par défaut de l'assistant de formulaire est également POST, method :: post
est également __optional __.
La variable d'instance «@ tags» de «<% = render @ tags%>« obtient «Tag.all» du côté du contrôleur décrit plus loin.
C'est une manière peu familière d'écrire un modèle partiel, mais dans ce modèle partiel d'abréviation, _variable name.html.erb
correspondant au nom de la variable est appelée, et dans ce modèle partiel, une variable locale (dans le modèle partiel dans ce cas
Il peut être utilisé comme tag). Si vous l'obtenez sous forme de tableau comme
@ tags` cette fois, il sera affiché à plusieurs reprises autant de fois que le numéro du tableau dans le modèle partiel.
Cela peut être réécrit comme suit.
erb:views/tags/index.html.erb
<%= render partial: 'tag', locals: {tags: @tags} %>
erb:views/tags/_tag.html.erb
<% tags.each do |tag| %>
<div class="tags-index__tags--tag">
<%= tag.name %>(<%= tag.menu_tag_ids.count %>)
<%= link_to 'X', tag_path(tag), method: :delete, remote: true %>
</div>
<% end %>
La méthode de description cette fois est une abréviation de ceux-ci. [Rails Guide-Layout and Rendering](https://railsguides.jp/layouts_and_rendering.html#%E3%83%91%E3%83%BC%E3%82%B7%E3%83%A3%E3%83% AB% E3% 82% 92% E4% BD% BF% E7% 94% A8% E3% 81% 99% E3% 82% 8B)
Créez js (.erb) à appeler depuis le contrôleur.
En décrivant js ici, l'opération DOM est effectuée par jQuery qui se déclenche lorsque create et destroy sont respectivement appelés depuis le contrôleur.
Le .html ()
utilisé ici sera ajouté s'il n'y a pas d'élément, et sera réécrit s'il y a déjà un autre élément.
js (.erb) au moment de l'action de création
erb:views/tags/create.js.erb
<% if @tag.errors.any? %>
$(".tags-index--messages").html("<p><%= j(render partial: 'layouts/error_messages', locals: {model: @tag}) %></p>")
<% else %>
$(".tags-index--messages").html("<p><%= j(render partial: 'layouts/flash_messages', locals: {model: @tag}) %></p>")
$("#tags-index--tag-list").html("<%= j(render @tags) %>")
$("#tag_name").val('')
<% end %>
<% if @ tag.errors.any?%>
Vérifie s'il y a une erreur dans @ tag
lorsque le bouton d'envoi est enfoncé.
<détails> @ tag.save
a été essayé du côté contrôleur, js.erb est dans un état où il peut être vu si une erreur s'est déjà produite dans @ tag
. J'arrive.
D'autre part, la méthode ʻinvalid? Valide manuellement l'objet non sauvegardé. Normalement, le contrôle de validation est automatiquement exécuté lorsque l'objet est sur le point d'être sauvegardé (lorsque
.save est essayé), et cette fois l'action est divisée en fonction du succès ou de l'échec de
.save, donc manuellement ʻinvalide?
À nouveau. Plutôt que de le faire, il vaut mieux vérifier si une erreur s'est déjà produite au moment de .save
(.errors.any?
). </ détails>
Si une erreur se produit (espaces vides ou noms de balises en double)
-Ajouter ou réécrire les messages d'erreur de validation (error_messages.html.erb) à $ (". Tags-index - messages ")
Si aucune erreur ne s'est produite (la sauvegarde a réussi)
-Ajouter ou réécrire des messages flash (flash_message.html.erb) à $ (". Tags-index - messages ")
-Récrire la liste des balises ($ (" # tags-index - tag-list ")
)
-Effacer le nom du tag saisi sous la forme ($ (" # tag_name "). Val ('')
)
Sera exécuté.
js (.erb) pendant l'action de destruction
erb:views/tags/destroy.js.erb
$(".tags-index--messages").html("<p><%= j(render partial: 'layouts/flash_messages', locals: {model: @tag}) %></p>")
$("#tags-index--tag-list").html("<%= j(render @tags) %>")
Identique à la création. -Ajouter ou réécrire un message flash lorsque la balise est supprimée ・ Réécriture de la liste des tags
Sera exécuté.
Je décrirai les actions nécessaires cette fois sur le contrôleur
tags_controller.rb
class TagsController < ApplicationController
def index
@tags = Tag.all
@tag = Tag.new
end
def create
@tags = Tag.all
@tag = Tag.new(tag_params)
respond_to do |format|
if @tag.save
format.js { flash.now[:success] = "Je l'ai sauvé." }
else
format.js
end
end
end
def destroy
@tags = Tag.all
@tag = Tag.new
Tag.find(params[:id]).destroy
flash.now[:warning] = "Il a été supprimé."
end
private
def tag_params
params.require(:tag).permit(:name)
end
end
Cette fois, form_with de create et link_to de destroy spécifient chacun remote: true
(dans le cas de form_with, il est omis car c'est la valeur par défaut), donc les deux ne demandent que JS.
tags_controller.rb
def create
...
respond_to do |format|
if @tag.save
format.js { flash.now[:success] = "Je l'ai sauvé." }
else
format.js
end
end
end
respond_to do |format|
Est un paramètre de bloc qui divise le traitement en fonction du format de la demande.
Cette fois, nous ne supposons pas qu'une demande viendra en HTML (local: true
) pour ajouter / supprimer des balises, donc seulformat.js {traitement} ʻest décrit. Si vous voulez séparer le traitement lorsqu'une requête en HTML arrive, vous pouvez écrire
format.html {processing} et diviser le traitement selon la méthode de la requête. Si ʻif @ tag.save
réussit, mettez le message "Saved." ʻIn the
flash [: success] clé et passez-le à create.js.erb. En cas d'échec, seul le message d'erreur de validation sera affiché, donc le message flash ne sera pas utilisé, donc aucun traitement ne sera écrit après
format.js`, seul l'affichage sera affiché.
Comme mentionné ci-dessus, le «@ tag» où l'erreur de validation s'est produite à ce moment est passé à create.js.erb, et le traitement d'erreur (affichage du message d'erreur de validation) y est effectué.
L'action de destruction met le message "" Supprimé. "Sur la touche
flash [: warning]` et le transmet à destroy.js.erb.
[Rails Guide-Overview of Action Controller](https://railsguides.jp/action_controller_overview.html#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81 % A8% E3% 82% A2% E3% 82% AF% E3% 82% B7% E3% 83% A7% E3% 83% B3) Pikawaka - resoond_to [Qiita- [Rails] Méthode détaillée et explication pour afficher des messages simples à l'aide de messages flash](https://qiita.com/dice9494/items/2a0e92aba58a516e42e9#flash%E3%81%A8flashnow%E3%81%AE] % E4% BD% BF% E3% 81% 84% E5% 88% 86% E3% 81% 91% E6% 96% B9% E3% 81% AF)
Si vous avez des questions, des différences d'interprétation ou si vous pensez que quelque chose ne va pas avec la méthode de description, nous vous serions reconnaissants de bien vouloir le signaler dans les commentaires.
Merci d'avoir lu jusqu'au bout.
[Rails Guide-Layout and Rendering](https://railsguides.jp/layouts_and_rendering.html#%E3%83%91%E3%83%BC%E3%82%B7%E3%83%A3%E3%83% AB% E3% 82% 92% E4% BD% BF% E7% 94% A8% E3% 81% 99% E3% 82% 8B) [Rails Guide-Overview of Action Controller](https://railsguides.jp/action_controller_overview.html#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81 % A8% E3% 82% A2% E3% 82% AF% E3% 82% B7% E3% 83% A7% E3% 83% B3) Pikawaka - resoond_to [Qiita- [Rails] Méthode détaillée et explication pour afficher des messages simples à l'aide de messages flash](https://qiita.com/dice9494/items/2a0e92aba58a516e42e9#flash%E3%81%A8flashnow%E3%81%AE] % E4% BD% BF% E3% 81% 84% E5% 88% 86% E3% 81% 91% E6% 96% B9% E3% 81% AF)
Recommended Posts