error_messages 的未定义局部变量或方法“对象”

undefined local variable or method `object' for error_messages

我不确定此错误消息的来源。我正在关注 Hartl 的 railtutorial,但将其改编为我自己的应用程序。我正在研究第 10 章并添加密码重置。

当我收到错误消息时:在服务器发送带有 link 的电子邮件以重置密码后。然后我在浏览器中输入 link 并收到以下错误消息:

undefined local variable or method `object'
Extracted source (around line #2):
<% if object.errors.any? %>

这是指共享的错误信息文件,它没有改变,之前没有引起问题。 不知道该发什么给你看看是什么原因。

\views\shared_error_messages.html.erb

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

views\passwords_resets\edit.html.erb(跟随link时调用的页面):

<% provide(:title, 'Reset password') %>
<h1 class="center">Reset password</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= hidden_field_tag :email, @user.email %>

      <%= 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 "Update password", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

app\controllers\password_resets_controller.rb:

class PasswordResetsController < ApplicationController
  before_action :get_user,   only: [:edit, :update]
  before_action :valid_user, only: [:edit, :update]

  def new
  end

  def create
    @user = User.find_by(email: params[:password_reset][:email].downcase)
    if @user
      @user.create_reset_digest
      @user.send_password_reset_email
      flash[:info] = "An email is sent to you with password reset instructions"
      redirect_to root_url
    else
      flash.now[:danger] = "Email address not found"
      render 'new'
    end
  end

  def edit
  end

  def update
    if password_blank?
      flash.now[:danger] = "Password can't be blank"
      render 'edit'
    elsif @user.update_attributes(user_params)
      log_in @user
      flash[:success] = "Password has been reset."
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

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

    # Returns true if password is blank.
    def password_blank?
      params[:user][:password].blank?
    end

    # Before filters

    def get_user
      @user = User.find_by(email: params[:email])
    end

    # Confirms a valid user.
    def valid_user
      unless (@user && @user.activated? && @user.authenticated?(:reset, params[:id]))
        redirect_to root_url
      end

    # Checks expiration of reset token.
    def check_expiration
      if @user.password_reset_expired?
        flash[:danger] = "Password reset has expired."
        redirect_to new_password_reset_url
      end
    end
end

更新:在写这个问题时我发现当我从\views\shared_error_messages.html.erb中删除行<%= render 'shared/error_messages' %>时我不再有问题,新视图正确显示。然后它可以正常工作,因为我可以更改密码。但是,错误消息不会再出现(例如,当密码和密码确认不匹配时)。怎么办?

渲染时必须将对象传递给错误消息模板。您对呈现错误消息模板的调用现在应包括 object: f.object,如下所示:

<%= render "shared/error_messages", object: f.object %>

您的部分内容对 "object" 一无所知。您必须将 @user 对象传递给部分对象:

<%= render 'shared/error_messages', locals: {object: @user %>