nil的未定义方法`errors':用于显示Rails验证错误的NilClass

时间:2015-12-08 07:49:08

标签: ruby-on-rails validation

尝试在Rails中的验证视图中显示错误时,我得到undefined method 'errors' for nil:NilClass error。我按照这个例子Rails validation error messages displays the error messages and array,考虑了它的答案。

我在用户模型中进行验证的一个例子是:
         validates_length_of :dog_name, minimum: 0, maximum: 30, message: 'cannot have more than 30 characters'

查看代码

<% if @user.errors.any? %>
  <div id="errorExplanation">
    <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

用户控制器

class UsersController < ApplicationController
    #before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
    #:following, :followers]
    before_filter :requireLogin
    #before_action :requireDog

    def requireLogin
        if session[:user_id] == nil
            redirect_to "/"
        end
    end

    def requireDog
        @user = User.find(session[:user_id])
        if(@user.dog_name == "Empty")
            redirect_to "users/new/"
        end
    end

    def index
        @users = User.all
    end

    def show
        @user = User.find(params[:id])
        @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end

    def new
        @user = User.new
        @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end

    def update
        @user = User.find(params[:id])
        if @user.update_attributes(profile_params)
            redirect_to action: "show"
            # Handle a successful update.
            else
            render 'edit'
        end
    end

    def following
        @title = "Following"
        @user  = User.find(params[:id])
        @users = @user.following.paginate(page: params[:page])
        render 'show_follow'
    end

    def followers
        @title = "Followers"
        @user  = User.find(params[:id])
        @users = @user.followers.paginate(page: params[:page])
        render 'show_follow'
    end

    def going
        @title = "Going"
        @user  = User.find(params[:id])
        @users = @user.going.paginate(page: params[:page])
        render 'show_gather'
    end

    def create
        @user = User.new(profile_params)
        if @user.save
            redirect_to '/users'
            else
            render 'new'
        end
    end

    private
    def profile_params
        params.require(:user).permit(:dog_name, :photo, :dog_breed, :dog_gender, :dog_age)
    end

end

在其他示例中,不需要进一步修改用户模型/控制器。用户确实存在。我在模型或控制器中遗漏了什么吗?

1 个答案:

答案 0 :(得分:0)

首先,您最好切换到新的validates methods

#app/models/user.rb
class User < ActiveRecord::Base
   validates :dog_name, length: { in: 0..30, message: 'cannot have more than 30 characters'}
end

-

其次,不是每次都设置@title - 为什么不使用action_name

每次加载操作时,默认设置controller_nameaction_name变量,以便在控制器或视图中使用。为什么不在视图中使用action_name变量?

#app/views/layouts/application.html.erb
<title><%= action_name if controller_name == "Users" %></title>

要回答您的问题,导致错误是因为您尝试在不存在的变量上调用方法:

for nil:NilClass

Ruby有一种有趣的方式来发布未声明变量的异常 - 而不是外表说变量不存在,它在NilClass类下调用它。

作为开发人员,您需要阅读undeclared method的消息,并猜测它是未设置的变量...

因此,您的问题的解决方法是找到未设置变量的原因

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def new
      @user = User.new
   end

   def create
      @user = User.new profile_params
      redirect_to users_path if @user.save
   end
end

上述内容可让您保存用户,否则会重新呈现new操作(并显示错误)。

我认为您遇到的问题是,您明确在验证问题上加载了new操作,这会阻止其附加所需的数据。