Rails 7.0.4.3|Ruby 3.2.2
假设我有一个页面some_page.html.erb
。
它有一个部分呈现的用户授权表单,在提交时会导致user_controller.rb
。
如何根据控制器响应在此窗体中显示数据,而不刷新页面?
# some_page.html.erb
<div class="modal-container">
<%= render partial: 'sign_in' %>
</div>
# app/views/_sign_in.html.erb
<div class="sign-in-modal">
<%= form_with url: '/find_user', method: 'post', id: 'find-user', remote: true do |form| %>
<div class="form-input-field">
<%= form.label :login, 'Login' %><br>
<%= form.text_field :login %>
</div>
<div class="form-input-field">
<%= form.label :password, 'Password' %><br>
<%= form.password_field :password %>
</div>
<div>
<%= form.submit 'Sign in' %>
</div>
<div class="error-msg">
...
PLACE FOR THE ERROR
...
</div>
<% end %>
</div>
# users_controller.rb
def find_user
user = User.find_by login: params[:login], password: params[:password]
if user.nil?
# make form display error
else
# some successful authorization logic, i.e. redirect_to
end
end
我试着这样做:
if user.nil?
respond_to do |format|
flash[:notice] = 'NO USERS FOUND!'
format.html { render partial: 'pages/sign_in' }
end
end
<div class="error-msg"
<%= flash[:notice] %>
</div>
但它什么也不做,并在浏览器控制台中显示Form responses must redirect to another location
错误。只有当我重新加载页面时,它才会在表单中显示来自flash
的错误。
如果我添加状态500,就像在其他SO线程中建议的那样:format.html { render partial: 'pages/sign_in', status: :500 }
它只会擦除整个页面并在其位置呈现表单。
我该怎么办?
1条答案
按热度按时间zysjyyx41#
我认为如果你发送
422
,:unprocessable_entity
,这应该可以工作。这样一来,在Rails 7中默认拦截和处理响应的Turbo Drive就知道如何处理响应。
我不知道你为什么在这里只渲染了一部分,但大概你有一个原因。呈现整个页面是很正常的,即使它只是表单部分的一个小 Package 。
rails g scaffold Foo name password
生成一个scaffold。您将看到它在FooController的#create
和#update
方法中执行了非常类似的操作。