Même si vous utilisez form_with sans local: true, la partie du message d'erreur n'est généralement pas asynchrone.
J'ai essayé de l'afficher de manière asynchrone, je vais donc résumer la méthode.
Si vous n'ajoutez pas local: true à form_with, la communication se produira de manière asynchrone.
erb:app/views/tests/new.html.erb
<%= form_with model: @test do |f| %>      
  <%= f.text_field :name %>
  <%= render 'shared/err_msg' %>
  <%= f.submit %>
<% end %>
erb:app/views/shared/err_msg.html.erb
<div id='err_container' style='display: none'>
  <ul id='err_ul'>
    <!--Je reçois un message d'erreur ici-->
  </ul>
</div>
Controller
Lorsque @ test.save échoue, normalement render: new est utilisé pour afficher le fichier de vue pour la nouvelle action, mais ici il est décrit dans ʻapp / views / shared / err_msg.js.erb`. J'essaye d'exécuter JavaScript.
app/controller/tests_controller.rb
def index
  @test = Test.new
end
def create
  @test = Test.new(test_params)
  respond_to do |format|
    if @test.save
      format.js { redirect_to tests_url, notice: 'créé' }
    else
      @object  = @test
      format.js { render 'shared/error', status: :unprocessable_entity } #Statut dans le navigateur_Renvoie le code 422
    end
  end
end
private
def test_params
  params.require(:test).permit(:name)
end
Le style du message d'erreur entier est changé de display: none à display: block, et le message d'erreur est enveloppé dans li et affiché.
js:app/views/shared/err_msg.js.erb
let err_container = document.getElementById('err_container');
err_container.style.display = 'block';
let err_ul = document.getElementById('err_ul');
<% @object.errors.full_messages.each do |msg| %>
  err_ul.insertAdjacentHTML('afterbegin', '<li><%= msg %></li>');
<% end %>
        Recommended Posts