Rails 5 - 显示错误消息

时间:2017-04-19 22:02:23

标签: html ruby-on-rails ruby-on-rails-5

所以我目前有用户帐户创建和登录工作。当用户键入不满足我为模型设置的验证要求的字段时,我希望能够显示任何错误或验证消息。从一些例子中,我看到人们呈现了一个名为" _errors.html.erb"这是在共享文件夹中。但是,当我尝试这个时,它对我不起作用,我相信是这样的,因为我正在使用Rails 5.我已经测试了一下" _errors.html.erb"我相信"任何?" if语句的一部分不能按预期工作。

当用户输入的字段值不正确时,是否有人知道在视图上显示错误或验证的方法?谢谢!

_errors.html.erb

<% if object.errors.any? %>
    <div class="panel panel-warning errors">
      <div class="panel-heading">
        <h5><i class="glyphicon glyphicon-exclamation-sign"></i> Found errors while saving</h5>
      </div>

      <ul class="panel-body">
        <% object.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
<% end %>

用户 - new.html.erb

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Bootstrap 101 Template</title>

</head>
<body>

<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">TimeTracker</a>
    </div>
  </div>
</nav>

  <div class="loginContainer" align="center">
    <h1 align="center"><b>Sign Up</b></h1>

    <%= form_for @user do |u| %>
        <div class="container">

          <%= render 'shared/errors', object:@user %>


          <label><b>First Name</b></label>
          <%= u.text_field :first_name, placeholder: 'First Name' %>

          <label><b>Last Name</b></label>
          <%= u.text_field :last_name, placeholder: 'Last Name' %>

          <label><b>Username</b></label>
          <%= u.text_field :email, placeholder: 'Email Address' %>
          <!--<input type="text" placeholder="Enter Username" name="uname" required> -->

          <br><label><b>Password</b></label>
          <%= u.password_field :password, placeholder: 'Password' %>
          <!--<input type="password" placeholder="Enter Password" name="psw" required> -->

          <br><label><b>Confirm </b></label>
          <%= u.password_field :password_confirmation, placeholder: 'Confirm Password' %>

          </br>
          <br>
          <%= u.submit 'Sign Up', class: 'btn btn-primary' %>

          </br>
        </div>
    <% end %>

  </div>

</body>
</html>

用户会话 - new.html.erb

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Bootstrap 101 Template</title>

</head>
<body>

<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Time Tracker</a>
    </div>
  </div>
</nav>

<div class="loginContainer" align="center">

  <h1 align="center"><b>Log In</b></h1>

  <%= form_for @user_session do |u| %>
      <div class="container">


        <%= render 'shared/errors', object:@user_session %>

        <label><b>Email</b></label>
        <%= u.text_field :email, placeholder: 'Email Address' %>
        <!--<input type="text" placeholder="Enter Username" name="uname" required> -->

        <br>
        <label>
          <b>Password</b>
        </label>
        <%= u.password_field :password, placeholder: 'Password' %>
        <br>

        <!-- Feature not working, left in there just in case -->
        <!--<%= u.label 'Remember me' %> -->
        <!--<%= u.check_box :remember_me %> -->

        <%= u.submit 'Login', class: 'btn btn-primary' %>


      </div>
  <% end %>


  <div class="container" style="background-color:#D3D3D3">
    <%= link_to 'Forgot your password?', new_password_reset_path %>
  </div>
</div>

</body>
</html>

用户模型

class User < ApplicationRecord

  has_many :activities, dependent: :destroy
  has_many :categories, dependent: :destroy

  acts_as_authentic

    validates :first_name, presence: true, length: {minimum: 1}
    validates :last_name, presence: true, length: {minimum: 1}
    validates :email, presence: true, uniqueness: true, length: {minimum: 5}
    validates :password, :confirmation => true, length: {minimum: 4}
    validates :password_confirmation, presence: true

    def deliver_password_reset_instructions
      reset_perishable_token!
     PasswordResetMailer.reset_email(self).deliver_now
    end
  end

编辑 - 04/19 - 8:30 PM

仅使用名称和其他字段留空的示例空白提交。

  

UsersController处理#create as HTML参数:   {&#34; UTF8&#34; = GT;&#34;✓&#34 ;,   &#34; authenticity_token&#34; = GT;&#34; 9HH1kH8cPNfjO2LnsLHRSEATs0g5d95jAHUYX8ZXhF7cz335Vg0G8jvtJeCdPHnqYyCtuVDV9frZmdo1z2b1wg ==&#34 ;,   &#34;用户&#34; =&gt; {&#34; first_name&#34; =&gt;&#34; Ben&#34;,&#34; last_name&#34; =&gt;&#34;&#34 ;,&#34; e mail&#34; =&gt;&#34;&#34;,   &#34;密码&#34; =&gt;&#34; [已过滤]&#34;,&#34; password_confirmation&#34; =&gt;&#34; [已过滤]&#34;},   &#34;提交&#34; =&gt;&#34;注册&#34;}

     

(0.0ms)BEGIN用户存在(3.5ms)SELECT   1 AS FROM&#34;用户&#34;哪里更低(&#34;用户&#34;。&#34;电子邮件&#34;)=更低($ 1)限制   2美元[[&#34;电子邮件&#34;,&#34;&#34;],[&#34;限制&#34;,1]]

     

用户存在(0.5ms)SELECT 1 AS   一个FROM&#34;用户&#34;用户&#34;。&#34; persistence_token&#34; = $ 1 LIMIT $ 2   [[&#34; persistence_token&#34 ;,   &#34; 58253c420dea482caa7cc457f7a6d4f9e5c9ea5008c30d82c2da9cfc8a3cdb189   5cfb05b75797f54959fb7f621a9e223073e8721bf75df60f6bb72387d469eee&#34],   [&#34; LIMIT&#34;,1]]

     

用户存在(0.5ms)选择1作为一个FROM&#34;用户&#34;   在哪里&#34;用户&#34;。&#34;电子邮件&#34; = $ 1限制$ 2 [[&#34;电子邮件&#34;,&#34;&#34;],[&#34;限制&#34;,1]]
  (2.0ms)ROLLBACK

用户控制器

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

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = 'Account created'
      redirect_to home_path
    else
      flash[:notice] ='ERROR: Account was not created'
      redirect_to :back
    end
  end

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

  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
  end
end

用户会话控制器

class UserSessionsController < ApplicationController

  def new
    @user_session = UserSession.new
  end

  def create

    @user_session = UserSession.new(user_session_params)

    @user_session.remember_me = true

    if @user_session.save
      flash[:success] = 'Welcome back'
      redirect_to :back
    else
      flash[:notice] = 'Failed to log in'
      redirect_to :back
    end
  end

  def destroy
    current_user_session.destroy
    flash[:success] = 'Goodbye'
    redirect_to :back
  end

  private

  def user_session_params
    #params.require(:user_session).permit(:email,:password,:remember_me)
    params.require(:user_session).permit(:email,:password)

  end

end

固定用户控制器

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

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = 'Account created'
      redirect_to home_path
    else
      flash[:notice] ='ERROR: Account was not created'
      render 'users/new'
    end
  end

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

  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
  end
end

3 个答案:

答案 0 :(得分:1)

问题在于,为了使@user实例变量可用于视图,您需要渲染而不是重定向。

当您重定向时,您正在向用户发送一条回复,说“再次打我”。当后续请求进入时,操作将执行时间。第一次执行操作时@user实例变量可用,但基于操作中的逻辑,第二次没有填充错误(为什么会这样)。

请参阅How are Rails instance variables passed to views?

问题可能是以下任何一个步骤:

  1. 请求可能无法路由到您期望的控制器。尝试查看服务器日志。当您在控制台中使用rails serverrails s启动服务器时,该窗口将显示所有传入的请求,并且它将显示受到影响的控制器+操作。例如:
  2. 来自我的测试应用的示例:

    code/blog [master●] » rails s
    => Booting Puma
    => Rails 5.0.2 application starting in development on http://localhost:3000
    => Run `rails server -h` for more startup options
    Puma starting in single mode...
    * Version 3.8.2 (ruby 2.4.1-p111), codename: Sassy Salamander
    * Min threads: 5, max threads: 5
    * Environment: development
    * Listening on tcp://localhost:3000
    Use Ctrl-C to stop
    Started GET "/" for ::1 at 2017-04-19 17:55:42 -0700
      ActiveRecord::SchemaMigration Load (0.4ms)  SELECT "schema_migrations".* FROM "schema_migrations"
    Processing by UncategorizedPagesController#home as HTML
      Rendering uncategorized_pages/home.html.erb within layouts/application
      Rendered uncategorized_pages/home.html.erb within layouts/application (1.4ms)
      Rendered partials/_navbar.html.erb (0.8ms)
    Completed 200 OK in 293ms (Views: 291.3ms | ActiveRecord: 0.0ms)
    

    您可以在此处看到请求为GET /,并且它会点击home的{​​{1}}操作。更确切地说,您可以在控制器操作中添加UncategorizedPagesController,并在服务器日志中查找“点击此操作”。

    1. 表单可能没有发送您希望他们发送到服务器的有效负载。尝试检查控制器中的params哈希值。如链接所述,puts "hits this action"哈希将包含您在表单中提交的数据。 IE浏览器。您的控制器中的params可能是params[:email]。您可以通过向控制器操作添加foo@bar.com并在达到相应路径后检查服务器日志来测试此情况。

    2. 验证可能没有像您期望的那样。要测试这一点,请尝试使用控制台(在沙盒模式下,这样就不会弄乱您的实际数据库),如下所示:

    3. 控制台输出:

      puts params

      您还应该使用单元测试来确保您的验证按预期工作。请参阅下面的Rails Tutorial

      中的示例
      $ rails console --sandbox
      >> user = User.new(name: "", email: "mhartl@example.com")
      >> user.valid?
      => false
      >> user.errors.full_messages
      => ["Name can't be blank"]
      
      1. 您可能无法触发验证。来自官方RailsGuide
      2.   

        以下方法会触发验证,并将对象保存到   仅当对象有效时才使用数据库:

             
            
        • 创建
        •   
        • 创建!
        •   
        • 保存
        •   
        • 保存!
        •   
        • 更新
        •   
        • 更新<!/ LI>   
             

        爆炸版本(例如   save!)如果记录无效,则引发异常。非爆炸   版本不:保存和更新返回false,并创建只返回   对象。

        1. 您的控制器逻辑可能没有将错误的用户发送回视图。要对此进行测试,请使用RailsGuide中提到的任何方法打印其中一个require 'test_helper' class UserTest < ActiveSupport::TestCase def setup @user = User.new(name: "Example User", email: "user@example.com") end test "should be valid" do assert @user.valid? end test "name should be present" do @user.name = "" assert_not @user.valid? end test "email should be present" do @user.email = " " assert_not @user.valid? end end 文件中的完整@usernew.html.erb是一种选择。

        2. 在尝试呈现debug(@user)部分时,您可能无法引用正确的文件。要对此进行测试,请尝试使用_errors.html.erb

        3. 渲染部分
        4. 您可能无法正确地将对象传递给部分。要对此进行测试,请尝试使用RailsGuide中提到的任何方法从视图中注销对象。 hello world是一种选择。

        5. 虽然看起来你正在做得很好。来自the docs

            

          如果您不打算使用任何选项(如集合或布局),您还可以使用渲染的简写默认值来渲染部分。例子:

          debug(object)

答案 1 :(得分:0)

尝试更换:

<%= render 'shared/errors', object:@user %>

使用:

<%= render 'shared/errors', object: u.object %>

答案 2 :(得分:0)

为您的用户控制器试用此功能

def create
  @user = User.new(user_params)
    if @user.save
      flash[:success] = 'Account created'
      redirect_to home_path
    else
      flash[:notice] ='ERROR: Account was not created'
      render :new
    end
end

我在Rails 5中遇到了这个问题,这对我有用。