【问题标题】:undefined method `email' for nil:NilClass link.user.emailnil 的未定义方法“电子邮件”:NilClass link.user.email
【发布时间】:2015-12-24 18:02:19
【问题描述】:

在我的index.html.erb 文件中,我得到了一个未定义的电子邮件方法。我进入 Rails 控制台并尝试运行 User.first.email,它运行良好。我尝试取出电子邮件并运行link.user,这也奏效了。我不确定当用户绑定到链接并且用户有电子邮件时,为什么电子邮件会被视为未定义。我正在寻找一些关于可能出现问题的建议。

Index.html.erb

<%= link.user.email %>

已运行迁移的架构

create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false

型号:

class Link < ActiveRecord::Base
    belongs_to :user
    validates :user, presence: true
    acts_as_votable
    attr_accessor :avatar
    mount_uploader :avatar, AvatarUploader
end

class User < ActiveRecord::Base
    has_many :links
    acts_as_voter
    devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

链接控制器:

class LinksController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show]

  def index
    @links = Link.all
  end

  def show
    @link = Link.find(params[:id])
  end

  def new
    @link = Link.new
  end

  def edit
  end

  def create
    @link = Link.new(link_params)

    if @link.save
      redirect_to root_path
    else
      render 'new'
    end
  end

    private
    def link_params
      params.require(:link).permit(:title, :url, :avatar, :user_id)
    end
end

错误信息:

User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
  Rendered links/_form.html.erb (2.7ms)
  Rendered links/new.html.erb within layouts/application (3.8ms)
Completed 200 OK in 505ms (Views: 143.6ms | ActiveRecord: 0.4ms)

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-3.2


    【解决方案1】:
    undefined method `email' for nil:NilClass link.user.email
    

    您收到此错误是因为link.user 对于某些链接是nil,因此它调用nil.email 并失败并显示上述错误消息。

    您可以像这样使用try 来解决这个问题:

    <%= link.user.try(:email) %>
    

    即使在某些情况下link.usernil,您的程序也不会崩溃。

    【讨论】:

    • 我确实有一个问题,如果有用户并且用户已登录,为什么您认为电子邮件会显示为 Nil?我很难看到这怎么可能是 Nil
    • 根据错误信息,link.user 在某些情况下会返回nil,这意味着有些链接与任何用户都没有关联。因此,对于这些链接,link.usernil。对于这种情况,如果您尝试:link.user.email,那么它会转换为:nil.email,这就是您收到错误消息的原因:undefined method email' for nil:NilClass`。
    • 好吧,这是有道理的。现在我只需要弄清楚为什么我的链接和用户之间的关联不起作用?我有我的链接类,它属于一个用户,一个用户有很多链接。不完全确定为什么它不会获取外键。
    • user 上的try 不会假定user 存在吗? IE 它不会实现 OP 想要的?
    • @Jbur43 如果您没有对 Link 对象始终拥有关联用户的任何验证,那么您可能以某种方式创建了一个链接,但没有将任何用户与其关联。但是,您可以在 Link 模型中添加对关联用户存在的验证,如下面 Rich Peck 的回答所示。这将防止在没有用户的情况下创建任何链接。但是,这不会修复您在数据库中已有的任何先前数据。因此,您必须通过手动将用户关联到它们来修复没有用户的现有 Link 对象。
    【解决方案2】:

    我知道你接受了另一个答案,但我认为它不正确。


    该错误表示您的link 没有关联的user 对象。

    如果您期望每个link 都有一个关联的user,则最好使用validation 以确保它在createupdate 上存在:

    #app/models/link.rb
    class Link < ActiveRecord::Base
       belongs_to :user
       validates :user, presence: true
    end
    

    这意味着每次创建link 时,它必须拥有一个User 对象;首先防止错误。

    --

    如果这就是您需要应用程序运行的方式(仅 IE 用户可以发布链接或其他方式),则您不需要在视图中使用 .nil?.try() 条件语句。

    简而言之,我认为公认的答案就像在生锈上涂漆(没有冒犯等)。

    【讨论】:

    • 我认为,您说的Accepted answer is incorrect 是不正确的。他接受了这个答案,因为它可以防止他的程序崩溃。首先添加验证并防止此类错误肯定会更好,但想象一下 OP 可能已经在数据库中有他可能无法重置的 Link 对象,因为他仍然需要 try 方法来防止他的index 页面崩溃了。
    • 可能只是一个或几个没有关联用户的链接,在这种情况下,OP 可以在我在上面评论中提到的数据库中手动更新它们。希望它能澄清事实。如果您仍然认为我的回答不正确,请告诉我:)
    • 嘿 Rich,我尝试添加验证,但现在我无法提交新链接,因为用户不在那里,这是一件好事,因为现在我知道关联仍然无法正常工作.我很好奇,您或@KMRakibulIslam 是否明白为什么该协会在这种情况下不起作用?我仍然很难过。我发布了我的新模型。
    • 我还发布了我的 rails 日志。它在事务中显示它看到的是我的 user_id,但随后回滚事务?
    • @Jbur43 我认为您应该使用最新信息创建另一个问题。
    【解决方案3】:

    这个错误的原因是link.usernil。您必须检查它是否是nil,例如:

    <% if !link.user.nil? %>
      <%= link.user.email %>
    <% end %>
    

    【讨论】:

      【解决方案4】:

      对于特定的user,可能有一些emailnil,您可以使用try 来逃避undefined method for NilClass

      <%= link.try(:user).try(:email) %> 
      

      如果user 也为link 为零,它会为您节省

      <%= link.user.try(:email) %> 
      

      【讨论】:

        【解决方案5】:

        我认为您需要检查链接迁移文件

        class CreateLinks < ActiveRecord::Migration
        

        在这个文件中你需要t.belongs_to :user_id

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-16
          相关资源
          最近更新 更多