Pendant le développement avec Rails, je m'inquiétais de la manière de gérer le rendu lors de l'implémentation du formulaire, j'ai donc pu reconfirmer la différence entre redirect_to et render lors de l'enquête, je vais donc le laisser comme un rappel. En passant, j'écrirai aussi que je m'inquiétais du rendu pendant un moment. (Plus précisément, gestion avant_action)
・ Rubis 2.6.5 ・ Rails 6.0.3
J'ai fait une demande d'enregistrement des informations du restaurant et défini les actions suivantes sur le contrôleur.
shops_controller.rb
def new
@shop = Shop.new
end
def create
@shop = @owner.shops.new(shop_params)
if @shop.save
redirect_to :index
else
render :new
end
end
J'ai écrit ceci sans plus réfléchir, mais si la sauvegarde échoue, pourquoi utiliser render pour revenir au formulaire de publication? Revenons là-dessus.
** En conclusion, je souhaite revenir à nouveau au formulaire de saisie tout en conservant le contenu d'entrée **.
Alors, pourquoi cela peut-il être réalisé en utilisant render au lieu de redirect_to? Revenons au comportement de redirect_to et render.
** redircet_to est un processus qui permet au côté client d'accéder à l'action (ou au chemin) spécifié. ** ** En conséquence, vous accéderez à la page après avoir revisité le flux de MVC. Plus précisément, le flux est "accéder à nouveau à l'action spécifiée ⇨ exécuter l'action du contrôleur ⇨ afficher la vue correspondante".
Cela fait exactement la même chose que d'accéder à la vue d'action à partir de l'URL.
Render, par contre, affiche simplement la vue correspondant à l'action spécifiée sans passer par l'action ** à nouveau. ** ** Contrairement à redirect_to, il renvoie la vue sans exécuter le contenu de la nouvelle action.
Jetons à nouveau un coup d'œil au code en fonction de l'explication ci-dessus.
shops_controller.rb
def new
@shop = Shop.new
end
def create
@shop = @owner.shops.new(shop_params)
if @shop.save
redirect_to :index
else
render :new
end
end
Puisque la nouvelle action est une nouvelle page d'inscription pour les informations sur la boutique, @ shop = Shop.new est défini dans l'action. (Créer une instance vide) Après cela, la valeur saisie dans le formulaire est transmise en tant que paramètres, et elle peut être enregistrée en la transmettant avec succès en tant qu'information de @shop créée cette fois par l'action de création.
Si l'enregistrement échoue (dans le cas de else), il sera de nouveau renvoyé au formulaire, mais si ** redirect_to est utilisé à ce moment, la nouvelle action sera exécutée à nouveau et @shop redeviendra une instance vide. ** **
En revanche, si vous utilisez ** render, la nouvelle action n'est pas utilisée, donc @shop affichera à nouveau la vue formulaire tout en conservant les valeurs des paramètres reçus par l'action de création. ** **
haml:new.html.haml
.shop-wrapper
= form_with model: [@owner, @shop], html: {class: "shopform"}, local: true do |f|
Ce qui précède est un extrait de la vue, mais comme le formulaire reçoit @owner et @shop et affiche le contenu, si le @shop a du contenu, il affichera le contenu correctement.
C'est pourquoi vous devez utiliser le rendu lorsque l'action de création échoue.
À propos, lorsque j'ai défini le rendu cette fois, j'ai rencontré pour la première fois l'erreur suivante.
Pendant un moment, cela s'est produit, mais j'ai défini le before_aciton suivant pour la nouvelle action.
shops_controller.rb
before_action :set_select_lists, only: [:new]
#Omission
private
def set_select_lists
@stations = Station.all.map {|station| [station.name, station.id] }.unshift(["Veuillez choisir parmi les suivants", nil])
@genres = Genre.all.map {|genre| [genre.name, genre.id] }.unshift(["Veuillez choisir parmi les suivants(Obligatoire)", nil])
@marks = Mark.all.map {|mark| [mark.favorite, mark.id] }.unshift(["Veuillez choisir parmi les suivants(Obligatoire)", nil])
end
J'ai créé une liste de sélection déroulante dans le formulaire et l'ai définie avec before_action.
Comme je l'ai écrit précédemment, le rendu ne passe pas à nouveau par la nouvelle action, donc ** before_action n'est pas effectué → Il n'y a pas de valeur définie et une erreur se produit dans l'affichage de la vue **.
En réponse à cela, pendant un moment, j'ai pensé: "S'il y a une variable que je dois définir de manière inattendue chez @shop, puis-je utiliser render?", Mais après avoir réfléchi pendant quelques minutes, je l'ai résolue immédiatement.
Réécrivez l'action de création comme suit.
shops_controller.rb
def create
@shop = @owner.shops.new(shop_params)
if @shop.save
else
set_select_lists
render :new
end
end
En exécutant set_select_lists qui a été fait dans before_action avant le rendu avec l'action de création, vous pouvez effectuer le rendu avec la valeur également acquise (le rendu effectue uniquement l'action de création, puis crée une nouvelle vue. Parce qu'il est affiché)
Pour un moment? ?? ?? Mais ce n'était pas une histoire si compliquée.
En fait, le comportement de redirect_to et render a été l'endroit où j'ai touché pour la première fois à la programmation avec Progate et a été le plus perturbé depuis environ un mois. Quand j'ai remarqué la différence ici, j'ai eu l'image que ma compréhension de MVC s'est approfondie en même temps.
J'espère que cela sera utile pour les débutants comme moi.
Recommended Posts