在控制器中渲染视图后出现 nil 的 NoMethodError

NoMethodError for nil after rendering view in controller

所以我有这个看法_form.erb:

<div class="form-group">
    <%= f.label :start_hour %><br>
    <%= f.select :start_hour, @select_hours.map {|value| [value, value]} %>
</div>

edit.erb中的这个:

<%= render 'form' %>

这在我的控制器中

    def edit
        @user = current_user
        @employee = @user.employee
        @hour = @employee.working_hours.find(params[:id])
        @select_hours = Array.new
        for i in 0..12
          @select_hours.push("#{07+i}:00")
          @select_hours.push("#{07+i}:30")
        end
    end

然后在我的控制器中进行更新

def update
    @employee = current_user.employee
    @hour = @employee.working_hours.find(params[:id])
    if @hour.update(working_hour_params)
      redirect_to employee_working_hours_path(@employee)
    else
      render :edit
    end
end

这是我的问题:

当我点击更新并且出现错误 start_hour(自定义验证,在创建而不是编辑时有效),因此 @hour 将不会更新。它再次呈现此视图,但错误是 nil 没有方法 map(因此 @select_hours)。

那么我该如何解决这个问题?

您可以在您的控制器中使用回调并为这两个操作设置 @select_hours,这样如果更新失败,该值将存在,但您不必为变量赋值两次, 比如:

before_action :set_select_hours, only: %i[edit update]
before_action :set_employee,     only: %i[edit update]
before_action :set_hour,         only: %i[edit update]

def edit; end

def update
  if @hour.update(working_hour_params)
    redirect_to employee_working_hours_path(@employee)
  else
    render :edit
  end
end

private

def set_select_hours
  @select_hours = (0..12).flat_map do |index|
    ["#{07 + index}:00", "#{07 + index}:30"]
  end
end

def set_employee
  @employee = current_user.employee
end

def set_hour
  @hour = @employee.working_hours.find(params[:id])
end

我认为@employee 也可以在 before 回调中设置。

我添加了平面图来创建和填充从范围开始的数组,它和以前一样是 "same",只是你不需要初始化数组,使用 for 循环,然后推送它的内容。