Flo*_*fia 6 ruby ruby-on-rails
我有一个名为视图new.html.erb在客户端localhost:3000/clients/new。我验证它的错误。如果有错误,我将再次渲染新视图以显示所有错误。问题是它localhost:3000/clients在我的浏览器中显示为而不是localhost:3000/clients/new。这是为什么?难道“渲染”应该不更改URL中的任何内容吗?当我刷新页面时,这会产生问题,因为我没有“索引”视图,并且触发了错误,而不是按预期显示“新”视图。
new.html.erb
<% if @client.errors.any? %>
<div class="alert alert-danger">
<h4 class="alert-heading">Error</h4>
<% @client.errors.full_messages.each do |msg| %>
<p><%= msg %></p>
<% end %>
</div>
<% end %>
<%= form_for @client, url: clients_path, remote: false do |f| %>
<div class="form-group row"><label class="col-sm-2 col-form-label">*Name</label>
<div class="col-sm-3">
<%= f.text_field :name, class:"form-control" %>
<% if @client.errors[:name].any? %>
<script>$('#client_name').css('border-color', 'red');</script>
<% end %>
</div>
</div>
<div class="col-sm-4 col-sm-offset-2">
<%= f.submit "Submit", id:"submit", class: 'btn btn-primary btn-sm'%>
<%= link_to "Cancel", controller:"mainpages", action:"index", :html=>{:class=> "btn btn-primary btn-sm"}%>
</div>
<% end %>
Run Code Online (Sandbox Code Playgroud)
clients_controller.rb
def new
@client = Client.new
end
def create
@client = Client.new(client_params)
if @client.save
return redirect_to :root
end
render 'new'
end
Run Code Online (Sandbox Code Playgroud)
routes.rb
root to: "mainpages#index"
get '/mainpages', controller: 'mainpages', action: 'index'
get '/planes', controller: 'planes', action: 'planes'
resources :clients
resources :planes
Run Code Online (Sandbox Code Playgroud)
client.rb
class Client < ApplicationRecord
validates :name, presence: true
end
Run Code Online (Sandbox Code Playgroud)
max*_*max 12
您的期望是完全错误的,但在 Rails 初学者中很常见。
在Rails 风格中,REST GET /clients/new只是一个包含用于创建新资源的表单的页面。因为它是一个 GET 请求,所以它是幂等的——这意味着它是无状态的,对于所有访问者来说都是一样的。
当您提交表单时,您的浏览器会将 POST 请求发送到/clients. 同样在 Rails 风格的 REST 中,这就是您创建资源的方式。
如果验证失败 rails 只会呈现包含表单的响应。这不应该重定向用户,因为您看到的是非幂等 POST 请求的结果。这与GET /clients/new.
其实render 'new'只是一个捷径render 'app/views/clients/new.html.erb'。两个端点共享一个视图 - 没有别的。
这是为什么?难道“渲染”不应该改变 URL 中的任何内容吗?
你完全错了。render不会更改 URL。之前提交表单更改了浏览器中的 URL。Render 只是呈现视图并将其作为响应的主体返回。如果您想了解客户端和服务器之间的交换实际上是如何工作的,请查看 Rails 应用程序的日志。
您可以将此与redirect_to发送location回标头和正确的响应代码 (302)进行对比,后者会将浏览器重定向到新位置。
这会在我刷新页面时出现问题,因为我没有“索引”视图并且它触发了错误而不是按预期显示“新”视图。
要解决此问题,您需要添加一个索引操作,该操作可以是简单的重定向到/clients/new. 当您重新加载页面时,您将发送一个 GET 请求,/clients该请求应呈现索引。
我真的建议您尝试只创建一个脚手架式 Rails 应用程序,以便在开始强加自己的想法之前了解 rails 约定如何进行简单的 CRUD 操作。
/clients提交无效数据后显示URL的原因是,如果您使用Rails默认值,那么/clients/new表单将提交在clients#create其下注册的请求POST /clients。
如果您的数据有效,Rails会将用户重定向到根路径GET /。如果您的数据无效,它将render :new作为响应POST /clients显示/clients在您的浏览器中。
如果您在提交无效数据后尝试刷新页面,浏览器应询问类似“您是否要重新提交表单?”之类的内容。如果您单击“是”,则页面将刷新,并且不应该被点击GET /clients(通常会路由到clients#index)。如果您手动单击您的Web浏览器的地址栏和命中Enter一个GET /clients请求,而不是发送,从而登陆你的错误的网页上。
通过运行rails routes命令,您可以查看所有路由,包括请求类型。
| 归档时间: |
|
| 查看次数: |
126 次 |
| 最近记录: |