use*_*916 4 ruby ruby-on-rails
我正在遵循Rails 教程,在注册表单中,如果提交了无效的用户信息,则应该重新呈现注册页面并显示错误消息,但实际上并没有。看来即使注册页面是由 渲染的"render \'new\'",传递给它的@user 也是空的。如何解决这个问题?
请注意,本教程使用 Rails 6,但我实际上使用的是 Rails 7.0.2.3 和 Ruby 3.1.1。不确定这是否是原因。
\n应用程序/控制器/user_controller.rb
\nclass UsersController < ApplicationController\n def new\n @user = User.new\n end\n\n def create\n @user = User.new(user_params)\n if @user.save\n else\n render \'new\'\n end\n end\n\n def show\n @user = User.find(params[:id])\n end\n\n private\n\n def user_params\n params.require(:user).permit(:name, :email, :password, :password_confirmation)\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n应用程序/视图/用户/new.html.erb
\n<% provide(:title, \'Sign up\') %>\n<h1>Sign up</h1>\n\n<div class="row">\n <div class="col-md-6 col-md-offset-3">\n <%= form_with(model: @user, local: true) do |f| %>\n <%= render \'shared/error_messages\' %>\n <%= f.label :name %>\n <%= f.text_field :name, class: \'form-control\' %>\n <%= f.label :email %>\n <%= f.email_field :email, class: \'form-control\' %>\n <%= f.label :password %>\n <%= f.password_field :password, class: \'form-control\' %>\n <%= f.label :password_confirmation, "Confirmation" %>\n <%= f.password_field :password_confirmation, class: \'form-control\' %>\n <%= f.submit "Create my account", class: "btn btn-primary" %>\n <% end %>\n </div>\n</div>\nRun Code Online (Sandbox Code Playgroud)\n应用程序/视图/共享/_error_messages.html.erb
\n<% if @user.errors.any? %>\n <div id="error_explanation">\n <div class="alert alert-danger">\n The form contains <%= pluralize(@user.errors.count, "error") %>.\n </div>\n <ul>\n <% @user.errors.full_messages.each do |msg| %>\n <li><%= msg %></li>\n <% end %>\n </ul>\n </div>\n<% end %>\nRun Code Online (Sandbox Code Playgroud)\n应用程序/资产/样式表/custom.scss
\n@import "bootstrap-sprockets";\n@import "bootstrap";\n\n/* variables */\n\n$gray-medium-light: #eaeaea;\n\n/* mixins */\n\n@mixin box_sizing {\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n/* miscellaneous */\n\n.debug_dump {\n clear: both;\n float: left;\n width: 100%;\n margin-top: 45px;\n @include box_sizing;\n}\n\n/* universal */\n\nbody {\n padding-top: 60px;\n}\n\nsection {\n overflow: auto;\n}\n\ntextarea {\n resize: vertical;\n}\n\n.center {\n text-align: center;\n\n h1 {\n margin-bottom: 10px;\n }\n}\n\n/* typography */\n\nh1, h2, h3, h4, h5, h6 {\n line-height: 1;\n}\n\nh1 {\n font-size: 3em;\n letter-spacing: -2px;\n margin-bottom: 30px;\n text-align: center;\n}\n\nh2 {\n font-size: 1.2em;\n letter-spacing: -1px;\n margin-bottom: 30px;\n text-align: center;\n font-weight: normal;\n color: $gray-light;\n}\n\np {\n font-size: 1.1em;\n line-height: 1.7em;\n}\n\n/* header */\n\n#logo {\n float: left;\n margin-right: 10px;\n font-size: 1.7em;\n color: white;\n text-transform: uppercase;\n letter-spacing: -1px;\n padding-top: 9px;\n font-weight: bold;\n\n &:hover {\n color: white;\n text-decoration: none;\n }\n}\n\n/* footer */\n\nfooter {\n margin-top: 45px;\n padding-top: 5px;\n border-top: 1px solid $gray-medium-light;\n color: $gray-light;\n\n a {\n color: $gray;\n\n &:hover {\n color: $gray-darker;\n }\n }\n\n small {\n float: left;\n }\n\n ul {\n float: right;\n list-style: none;\n\n li {\n float: left;\n margin-left: 15px;\n }\n }\n}\n\n/* sidebar */\n\naside {\n section.user_info {\n margin-top: 20px;\n }\n\n section {\n padding: 10px 0;\n margin-top: 20px;\n\n &:first-child {\n border: 0;\n padding-top: 0;\n }\n\n span {\n display: block;\n margin-bottom: 3px;\n line-height: 1;\n }\n\n h1 {\n font-size: 1.4em;\n text-align: left;\n letter-spacing: -1px;\n margin-bottom: 3px;\n margin-top: 0px;\n }\n }\n}\n\n.gravatar {\n float: left;\n margin-right: 10px;\n}\n\n.gravatar_edit {\n margin-top: 15px;\n}\n\n/* forms */\n\ninput, textarea, select, .uneditable-input {\n border: 1px solid #bbb;\n width: 100%;\n margin-bottom: 15px;\n @include box_sizing;\n}\n\ninput {\n height: auto !important;\n}\n\n#error_explanation {\n color: red;\n ul {\n color: red;\n margin: 0 0 30px 0;\n }\n}\n\n.field_with_errors {\n @extend .has-error;\n .form-control {\n color: $state-danger-text;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n单击表单提交按钮无效时 Rails 服务器的调试信息
\nStarted POST "/users" for ::1 at 2022-04-06 00:55:04\nProcessing by UsersController#create as TURBO_STREAM\n Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"name"=>"foo123", "email"=>"foo123@asdf", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create my account"}\n TRANSACTION (0.0ms) begin transaction\n \xe2\x86\xb3 app/controllers/users_controller.rb:8:in `create\'\n User Exists? (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "foo123@asdf"], ["LIMIT", 1]]\n \xe2\x86\xb3 app/controllers/users_controller.rb:8:in `create\'\n TRANSACTION (0.0ms) rollback transaction\n \xe2\x86\xb3 app/controllers/users_controller.rb:8:in `create\'\n Rendering layout layouts/application.html.erb\n Rendering users/new.html.erb within layouts/application\n Rendered shared/_error_messages.html.erb (Duration: 0.4ms | Allocations: 403)\n Rendered users/new.html.erb within layouts/application (Duration: 1.9ms | Allocations: 1891)\n Rendered layouts/_shim.html.erb (Duration: 0.0ms | Allocations: 15)\n Rendered layouts/_header.html.erb (Duration: 0.1ms | Allocations: 78)\n Rendered layouts/_footer.html.erb (Duration: 0.1ms | Allocations: 51)\n Rendered layout layouts/application.html.erb (Duration: 9.5ms | Allocations: 8695)\nCompleted 200 OK in 213ms (Views: 9.8ms | ActiveRecord: 0.2ms | Allocations: 11628)\nRun Code Online (Sandbox Code Playgroud)\n
Ale*_*lex 13
TURBO_STREAM在 Rails 7 中,表单默认提交。提交表单后,Turbo 预计会重定向,除非响应状态在 400-599 范围内。
render :new # default status is 200
Run Code Online (Sandbox Code Playgroud)
状态代码 200 Turbo 在浏览器控制台中显示错误,并且页面不会重新呈现。
要使 Turbo 接受渲染的 html,请更改响应状态。默认值似乎是:unprocessable_entity(状态代码 422)
render :new, status: :unprocessable_entity
Run Code Online (Sandbox Code Playgroud)
https://turbo.hotwired.dev/handbook/drive#redirecting-after-a-form-submission
https://github.com/hotwired/turbo/commit/4670f2b57c5d0246dfc0f6d10ff7d9a52a63fdca
更新:关于“内容类型”的注释。这适用于使用 Turbo 的默认表单提交。
在此设置中,Turbo期待 html 响应Content-Type: text/html;。@puerile 指出,在视图中省略.html扩展名也会破坏响应。
Rails 使用.html扩展名将响应内容类型设置为text/html. 当省略扩展名时,内容类型设置为,因为表单以TURBO_STREAMtext/vnd.turbo-stream.html形式提交,因为我们的响应没有 a它是错误的内容类型。<turbo-stream>
>> Mime[:turbo_stream].to_str
=> "text/vnd.turbo-stream.html"
Run Code Online (Sandbox Code Playgroud)
如果我们有一个 view views/users/new.erb,这将不起作用:
if @user.save
redirect_to @user
else
# NOTE: this will render `new.erb` and set
# `Content-Type: text/vnd.turbo-stream.html` header;
# turbo is not happy.
render :new, status: :unprocessable_entity
end
Run Code Online (Sandbox Code Playgroud)
要修复它,请使用respond_to方法:
respond_to do |format|
if @user.save
format.html { redirect_to @user }
else
# NOTE: this will render `new.erb` and set
# `Content-Type: text/html` header;
# turbo is happy.
format.html { render(:new, status: :unprocessable_entity) }
end
end
Run Code Online (Sandbox Code Playgroud)
或手动设置内容类型:
if @user.save
redirect_to @user
else
render :new, status: :unprocessable_entity, content_type: "text/html"
# NOTE: you can also set headers like this
headers["Content-Type"] = "text/html"
end
Run Code Online (Sandbox Code Playgroud)
最后设置的一个警告是,布局也必须没有.html扩展名,否则,将在没有布局的情况下render :new渲染new.erb ,并且Turbo将不再满意。使用方法时这不是问题respond_to。
https://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to
如果您查看日志,您可以看到 Rails 正在以 Turbo 流的形式获取 AJAX 请求:
Processing by UsersController#create as TURBO_STREAM
Run Code Online (Sandbox Code Playgroud)
应该在哪里读:
Processing by UsersController#create as HTML
Run Code Online (Sandbox Code Playgroud)
要禁用涡轮增压,您需要data-turbo="false"在表单上设置一个属性:
Processing by UsersController#create as TURBO_STREAM
Run Code Online (Sandbox Code Playgroud)
该local: false选项仅适用于旧的 Rails UJS javascript 库,这是 Rails 7 之前的默认库。您还可以通过以下方式默认禁用 Turbo:
Processing by UsersController#create as HTML
Run Code Online (Sandbox Code Playgroud)
看:
https://turbo.hotwired.dev/handbook/drive#disabling-turbo-drive-on-specific-links-or-forms
| 归档时间: |
|
| 查看次数: |
4342 次 |
| 最近记录: |