Rails 7 注册表单不显示错误消息

2024-03-14

我正在关注一个导轨教程 https://www.learnenough.com/ruby-on-rails-6th-edition-tutorial/sign_up#sec-signup_form,在注册表单中,如果提交了无效的用户信息,注册页面应该重新呈现并显示错误消息,但实际上并没有。看来即使注册页面是由"render 'new'",传递给它的@user 是空的。如何解决这个问题?

请注意,本教程使用 Rails 6,但我实际上使用的是 Rails 7.0.2.3 和 Ruby 3.1.1。不确定这是否是原因。

应用程序/控制器/user_controller.rb

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
    else
      render 'new'
    end
  end

  def show
    @user = User.find(params[:id])
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
end

应用程序/视图/用户/new.html.erb

<% 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>

应用程序/视图/共享/_error_messages.html.erb

<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

应用程序/资产/样式表/custom.scss

@import "bootstrap-sprockets";
@import "bootstrap";

/* variables */

$gray-medium-light: #eaeaea;

/* mixins */

@mixin box_sizing {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

/* miscellaneous */

.debug_dump {
  clear: both;
  float: left;
  width: 100%;
  margin-top: 45px;
  @include box_sizing;
}

/* universal */

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;

  h1 {
    margin-bottom: 10px;
  }
}

/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: $gray-light;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}

/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: white;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;

  &:hover {
    color: white;
    text-decoration: none;
  }
}

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-medium-light;
  color: $gray-light;

  a {
    color: $gray;

    &:hover {
      color: $gray-darker;
    }
  }

  small {
    float: left;
  }

  ul {
    float: right;
    list-style: none;

    li {
      float: left;
      margin-left: 15px;
    }
  }
}

/* sidebar */

aside {
  section.user_info {
    margin-top: 20px;
  }

  section {
    padding: 10px 0;
    margin-top: 20px;

    &:first-child {
      border: 0;
      padding-top: 0;
    }

    span {
      display: block;
      margin-bottom: 3px;
      line-height: 1;
    }

    h1 {
      font-size: 1.4em;
      text-align: left;
      letter-spacing: -1px;
      margin-bottom: 3px;
      margin-top: 0px;
    }
  }
}

.gravatar {
  float: left;
  margin-right: 10px;
}

.gravatar_edit {
  margin-top: 15px;
}

/* forms */

input, textarea, select, .uneditable-input {
  border: 1px solid #bbb;
  width: 100%;
  margin-bottom: 15px;
  @include box_sizing;
}

input {
  height: auto !important;
}

#error_explanation {
  color: red;
  ul {
    color: red;
    margin: 0 0 30px 0;
  }
}

.field_with_errors {
  @extend .has-error;
  .form-control {
    color: $state-danger-text;
  }
}

单击表单提交按钮无效时 Rails 服务器的调试信息

Started POST "/users" for ::1 at 2022-04-06 00:55:04
Processing by UsersController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"name"=>"foo123", "email"=>"foo123@asdf", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create my account"}
  TRANSACTION (0.0ms)  begin transaction
  ↳ app/controllers/users_controller.rb:8:in `create'
  User Exists? (0.1ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "foo123@asdf"], ["LIMIT", 1]]
  ↳ app/controllers/users_controller.rb:8:in `create'
  TRANSACTION (0.0ms)  rollback transaction
  ↳ app/controllers/users_controller.rb:8:in `create'
  Rendering layout layouts/application.html.erb
  Rendering users/new.html.erb within layouts/application
  Rendered shared/_error_messages.html.erb (Duration: 0.4ms | Allocations: 403)
  Rendered users/new.html.erb within layouts/application (Duration: 1.9ms | Allocations: 1891)
  Rendered layouts/_shim.html.erb (Duration: 0.0ms | Allocations: 15)
  Rendered layouts/_header.html.erb (Duration: 0.1ms | Allocations: 78)
  Rendered layouts/_footer.html.erb (Duration: 0.1ms | Allocations: 51)
  Rendered layout layouts/application.html.erb (Duration: 9.5ms | Allocations: 8695)
Completed 200 OK in 213ms (Views: 9.8ms | ActiveRecord: 0.2ms | Allocations: 11628)

在 Rails 7 中,表单提交为TURBO_STREAM默认情况下。提交表单后,Turbo 预计会重定向,除非响应状态在 400-599 范围内。

render :new  # default status is 200

状态代码 200 Turbo 在浏览器控制台中显示错误,并且页面不会重新呈现。

要使 Turbo 接受渲染的 html,请更改响应状态。默认似乎是:unprocessable_entity(状态代码 422)

render :new, status: :unprocessable_entity

https://turbo.hotwired.dev/handbook/drive#redirecting-after-a-form-submission https://turbo.hotwired.dev/handbook/drive#redirecting-after-a-form-submission

https://github.com/hotwired/turbo/commit/4670f2b57c5d0246dfc0f6d10ff7d9a52a63fdca https://github.com/hotwired/turbo/commit/4670f2b57c5d0246dfc0f6d10ff7d9a52a63fdca


Update:关于“内容类型”的注释。这适用于使用 Turbo 的默认表单提交。

在这个设定中turbo正在等待 html 响应Content-Type: text/html;。 @puerile 指出省略.html您的观点中的扩展也会破坏响应。

导轨用途.html将响应内容类型设置为的扩展text/html。当省略扩展名时,内容类型设置为text/vnd.turbo-stream.html因为表单提交为TURBO_STREAM,因为我们的响应没有<turbo-stream>这是错误的内容类型。

>> Mime[:turbo_stream].to_str
=> "text/vnd.turbo-stream.html"

如果我们有一个观点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

要修复它,请使用respond_to method:

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

或手动设置内容类型:

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

最后设置的一个警告是布局必须没有.html扩展也是如此,否则,render :new将渲染new.erb没有布局和turbo不会再幸福了使用时这不是问题respond_to method.


https://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to https://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails 7 注册表单不显示错误消息 的相关文章

  • 在新的 RHEL6 服务器上安装 ruby​​-filemagic gem 时遇到困难

    它似乎正在寻找 libmagic so 1 文件 我有那个文件 它位于 usr lib64 中 我没有以 root 用户身份运行此安装 我也在使用 rvm 和 Bundler 这是我的 bundle 命令的结果 当它到达 Gemfile 中
  • 如何使用 ruby​​ 的循环和 haml 创建表?

    我正在尝试制作一个如下所示的 html 表 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 我的数据结构是这样的 f ary 1 250 这是我的哈姆尔代码 table border gt 1 tbody tr cnt 0 f
  • Rails 中的并行方法

    我的 Rails Web 应用程序有数十种方法 从调用 API 到处理查询结果 这些方法具有以下结构 def method one batch query API process data end def method nth batch
  • 无需别名的 Ruby YAML 编写

    我正在从 ruby 将数据写入 yaml 文件 并且经常在该文件上添加别名 像 id001 somekey somevalue id001 就我而言 我使用 yaml 文件来aid可读性并将名称添加到文件中的值 因为现有数据只是 没有键的分
  • 在 ruby​​ 中读/写受密码保护和加密的文件

    我想加密一个 ruby 程序将从中加载数据的文件 此外 我需要程序在启动时提示输入密码 该密码将用于解密文件 换句话说 该文件需要加密地驻留在计算机上 只有拥有密码的用户才能运行该应用程序 我已经开始研究 openpgp 但据我了解 这仍然
  • 用于 RESTful 轨道应用程序的简单面包屑

    是否有任何辅助方法 除了默认 Rails 面包屑导航 http wiki rubyonrails org rails pages Breadcrumbs 为特定页面动态生成面包屑导航 而无需在 RESTful 应用程序中传递琐碎的参数 也就
  • 从部分重定向回具有部分的同一页面后保留验证错误

    因此 我试图从我的表单中获取错误 该表单在我的 root path 中呈现为部分内容 在我尝试发布它但失败 或成功 后 我想重定向回 root path 但是 redirect to 决定不保存任何验证信息 想知道如何做到这一点 class
  • Capybara 的 has_selector 有哪些选项?

    我在 RSpec 中遇到此错误 有没有任何文档have selector解释了选项哈希中的每个键以及它到底有什么作用 invalid keys content should be one of text visible between co
  • Memcachier 达到缓存限制时 Heroku 请求超时

    我使用 Memcachier Dalli 作为客户端 将 Rails 应用程序部署到 Heroku 我正在使用免费插件 提供 25 MB 缓存 我们开始收到来自heroku的请求超时 经过调试 我们发现手动刷新Memcachier解决了问题
  • Rails Searchkick / Elasticsearch has_many 和belongs_to 关联

    我尝试使用 Searchkick 运行搜索并基于多个模型返回 我的书本模型包含这个 class Book lt ActiveRecord Base searchkick has many book subjects has many sub
  • 使用 Minitest 测试自定义验证器

    我有多个带有电子邮件验证的模型 因此 我将验证提取到自定义验证器中 我按照以下教程做到了这一点导轨指南 http guides rubyonrails org active record validations html custom va
  • 自定义变形在rails3上不起作用?

    我正在使用 Rails 3 0 1 并在initializers inflections rb 中有以下代码 ActiveSupport Inflector inflections do inflect inflect irregular
  • 带有附加参数的redirect_to

    我是一个菜鸟 redirect to users url notice Succeed p p 然后我添加一个message它失败了 redirect to users url notice Succeed message test p p
  • 如何从rails控制台将数据添加到数据库

    我有一个User model gt gt u User new gt
  • Ruby 可选参数和多个参数

    我试图将方法的第一个参数设置为可选 后跟任意数量的参数 例如 def dothis value 0 args 我遇到的问题是 这似乎实际上不可能 当我打电话时dothis hey how are you good 我希望它将值设置为默认值
  • 在特定页面上执行 javascript 的正确“Rails”方式

    我试图在特定页面上运行 javascript 而我唯一的解决方案似乎是反模式 我有controller js内部生成的assets javascripts 我在用着gem jquery turbolinks 我的代码类似于以下内容 docu
  • 在 CircleCI 中设置 Elasticsearch 和 Ruby on Rails

    我正在尝试在 Rails 应用程序中使用 Elasticsearch 设置 CircleCI 我想已经配置了镜像 但是如何在 CI 中连接到它 到目前为止我已经尝试过 https github com elastic elasticsear
  • ||= 是什么意思? [复制]

    这个问题在这里已经有答案了 我的应用程序控制器中有一个受保护的方法 def current user current user User find by id session user id end 我想知道什么 方法 我一直在努力寻找和找
  • Rails 3.1+ 的 Jasmine 与 Mocha JavaScript 测试 [已关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我对茉莉花有经验并且非常喜欢它 有谁有 Jasmine 和 Mocha 的经验 特别是 Rails 的经验吗 我想知道是否值得转用 我已经在 J
  • Rails 4 的 mobile_fu

    我正在尝试将我的应用程序从 Rails 3 2 13 切换到 Rails 4 在此过程中 我遇到了一个主要障碍 我使用 gem mobile fu 来确定用户是否来自移动设备 该 gem 需要 Railties 3 2 13 但 Rails

随机推荐