The environment is as follows. Mac OS Catalina 10.15.7 Ruby 2.7.1 Rails 6.0.3.3
I will try to record it as easily as possible, also as a memorandum of my own. To illustrate the problem, we'll use the Rails tutorial as an example.
Specifically, when implementing the user registration function in Chapter 7, the URL will change from / signup
to / users
when it is rendered on the form screen after registration failure due to validation. The problem, that is
URL changes from localhost: 3000 / signup
to localhost: 3000 / users
→ An error occurs when reloading because the view corresponding to users is not created.
I will explain the solution to the problem.
When the user registration fails in the create action, render'new'
means that the new action is not called and only the view is switched.
Since the create action is / users, the URL will naturally be / users
after the action.
The inconsistency between this URL and the screen is a problem.
The solution is to change the URL with javascript without changing the controller code. Load a specific js only in the target view.
(Change from / users
to / signup
, that is, it looks like the URL is fixed as / signup
even after the action.)
procedure
Create the following js with any directory under app / javascript / packs or any name directly under it (users / signup_render.js in this case).
app/javascript/packs/users/signup_render.js
history.replaceState('', '', '/signup')
I referred to the following. Easy-to-understand explanation about replaceState Learn more about replaceState
I am editing the current history with the history.replaceState () method and replacing / users
with / signup
with the URL parameters passed to the method.
Create a new compilation setting in ʻapp / javascript / packs / application.js` to compile for the target view.
app/javascript/packs/application.js
//↓ Original code
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
//↓ Add this
require("users/signup_render")
The path is described starting from app / javascript.
Embed javascript_pack_tag
in the target view. In the tutorial example, it is the user registration screen shown in Listing 7.20.
erb:app/views/users/new.html.erb
<!--This is the original code ↓-->
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(model: @user, local: true) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
<!--Add this below ↓-->
<% if @user.errors.any? %>
<%= javascript_pack_tag 'users/signup_render' %>
<% end %>
ʻIf @ user.errors.any?` sets the condition "Validation error occurs = Please process js only when user registration fails and renders."
<% = javascript_pack_tag'users / signup_render'%>
means "load ʻapp / javascript / packs / users / signup_render.js`."
I hope you find this helpful.
-URL changes after Rails5 render'new' ・ [Rails] Reload measures when using render -[About the behavior of the URL after the validation error of the new action and the error that accompanies it](https://ja.stackoverflow.com/questions/36794/new%E3%82%A2%E3%82%AF%E3%82] % B7% E3% 83% A7% E3% 83% B3% E3% 81% AE% E3% 83% 90% E3% 83% AA% E3% 83% 87% E3% 83% BC% E3% 82% B7 % E3% 83% A7% E3% 83% B3% E3% 82% A8% E3% 83% A9% E3% 83% BC% E5% BE% 8C% E3% 81% AEurl% E3% 81% AE% E6 % 8C% 99% E5% 8B% 95% E3% 81% A8% E3% 81% 9D% E3% 82% 8C% E3% 81% AB% E4% BC% B4% E3% 81% 86% E3% 82 % A8% E3% 83% A9% E3% 83% BC% E3% 81% AB% E3% 81% A4% E3% 81% 84% E3% 81% A6) -Handling of Javascript files in Ruby on Rails (Rails 6)
Recommended Posts