nil:NilClass 的未定义方法“错误”-当我单击表单提交时

Posted

技术标签:

【中文标题】nil:NilClass 的未定义方法“错误”-当我单击表单提交时【英文标题】:Undefined method `errors' for nil:NilClass - when I click on Form Submit 【发布时间】:2022-01-13 13:23:39 【问题描述】:

我已向FORM 表单添加了验证。因此,每当我单击包含所有详细信息的创建员工时,它都会起作用,但是当我没有输入值时,我会收到此错误。我什至在 form_with 中改成了@employee。

我只想看到验证。我该如何处理?

员工控制器:

class EmployeesController < ApplicationController
  before_action :set_employee, only: %i[ show edit update destroy]

  # GET /employees or /employees.json
  def index
    @employees = Employee.all
  end

  # GET /employees/1 or /employees/1.json
  def show
  end

  # GET /employees/new
  def new
    @employee = Employee.new
  end

  # GET /employees/1/edit
  def edit
  end

  # POST /employees or /employees.json
  def create
    employee_service = EmployeeCreationService.new(employee_params)

    respond_to do |format|
      if employee_service.execute!
        format.html  redirect_to employee_service.employee
        # format.json  render :show, status: :created, location: @employee 
      else
        format.html  render :new, status: :unprocessable_entity 
        # format.json  render json: @employee.errors, status: :unprocessable_entity 
      end
    end
  end

  # PATCH/PUT /employees/1 or /employees/1.json
  def update
    respond_to do |format|
      if @employee.update(employee_params)
        format.html  redirect_to @employee
        # format.json  render :show, status: :ok, location: @employee 
      else
        format.html  render :edit, status: :unprocessable_entity 
        # format.json  render json: @employee.errors, status: :unprocessable_entity 
      end
    end
  end

  # DELETE /employees/1 or /employees/1.json
  def destroy
    @employee.destroy
    respond_to do |format|
      format.html  redirect_to employees_url
      # format.json  head :no_content 
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_employee
      @employee = Employee.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def employee_params
      params.require(:employee).permit(:name, :phone, :designation_id, :email, :password)
    end
end

表格:

<%= form_with(model: employee, local: true) do |form| %>
  <% if employee.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(employee.errors.count, "error") %> prohibited this employee from being saved:</h2>

      <ul>
      <% employee.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="form-group row">
    <%= form.label :name,class:"col-sm-2 col-form-label" %>
    <div class="col-sm-10">
    <%= form.text_field :name %>
    </div>
  </div>

  <div class="form-group row">
    <%= form.label :phone,class:"col-sm-2 col-form-label" %>
    <div class="col-sm-10">
    <%= form.text_field :phone %>
    </div>
  </div> 

 
 <div class="form-group row">
    <%= form.label :designation_id,class:"col-sm-2 col-form-label" %>
    <div class="col-sm-10">
    <%= form.select :designation_id, [["SOFTWARE ENGINEER", "2"], ["SERVICE ENGINEER", "3"]] %>
    
    </div>
  </div> 


  <div class="form-group row">
    <%= form.label :Email,class:"col-sm-2 col-form-label" %>
    <div class="col-sm-10">
    <%= email_field_tag 'employee[email]' %>
    </div>
  </div> 

   <div class="form-group row">
    <%= form.label :Password,class:"col-sm-2 col-form-label" %>
    <div class="col-sm-10">
    <%= password_field_tag 'employee[password]' %>
    </div>
  </div> 

<br />

  <div class='form-group'>
    <div class="align-left">
      <h5 align="left">
      <%= form.submit class:"btn btn-dark"%>
      </h5></button>

    </div>
  <div class="align">
    <div >&nbsp;
    <%= link_to 'Go Back', employees_path , class:"btn btn-primary btn-sm"%>
  </div>
  </div>
</div>
  

<% end %>

服务 - 同时创建员工和用户(使用设计):

class EmployeeCreationService
    attr_reader :employee
    def initialize(employee_params)
        @employee_params = employee_params.except(:email, :password)
        @user_params = employee_params.slice(:email, :password)
    end

    def execute!
        begin
            @employee = Employee.create!(@employee_params)
            User.create!(@user_params.merge(employee: employee))
        rescue => exception
            @ex =  exception
            return false  
        end
        true
    end
end

【问题讨论】:

你在做employee.errors.any?,试试@employee.errors.any? @arieljuod 不,它没有解决 【参考方案1】:

我认为else 条件分支中的create 操作存在问题: 表单需要设置@employee 变量,但不适用于这种情况。 您需要能够从您的服务中获得 Employee 类的实例。像这样的:

@employee = employee_service.execute!
if @employee.valid?
  redirect_to
else
  render 

【讨论】:

未定义的方法“有效吗?”对于 false:FalseClass,我得到了这个。我是 Rails 的新手 @Sameer_99 您需要更改服务类的实现 - 它应该返回的不是 True/False,而是 Employee 实例。 谢谢,我找到了解决办法【参考方案2】:
  def create
    @employee = Employee.new(employee_valid)
    employee_service = EmployeeCreationService.new(employee_params)
    

    respond_to do |format|
      if employee_service.execute!
        format.html  redirect_to employee_service.employee
        
      else
        format.html  render :new, status: :unprocessable_entity 
        
      end
    end
  end

进行了这些更改,现在可以正常工作了。对于验证,我添加了 JS。

还可以仅使用姓名电话和指定来分割员工参数。

【讨论】:

以上是关于nil:NilClass 的未定义方法“错误”-当我单击表单提交时的主要内容,如果未能解决你的问题,请参考以下文章

为啥删除代码行会在 simple_form 中产生“nil:NilClass 的未定义方法‘错误’”

部署到Heroku:NoMethodError:nil:NilClass的未定义方法'+'

nil:NilClass 的未定义方法“每个”,但我使用了实例变量

Rails 文件上传错误“nil:NilClass 的未定义方法‘original_filename’”

nil:NilClass 的未定义方法“original_filename”

nil:NilClass 的未定义方法 `upload' 你的意思是?加载