【问题标题】:NoMethodError in Users#index: undefined method `name'用户#index 中的 NoMethodError:未定义的方法“名称”
【发布时间】:2016-03-13 20:50:54
【问题描述】:

我在用户和帐户之间有关系:

用户属于一个帐户。一个帐户可以有多个用户。

关系有效,您可以在以下查询中看到:

2.1.4 :010 > User.last.account.name
  User Load (2.0ms)  SELECT  "users".* FROM "users"  WHERE "users"."deleted_at" IS NULL  ORDER BY "users"."id" DESC LIMIT 1
  Account Load (2.4ms)  SELECT  "accounts".* FROM "accounts"  WHERE "accounts"."deleted_at" IS NULL AND "accounts"."id" = $1 LIMIT 1  [["id", 4]]
 => "Account A" 

但是,如果我显示用户的索引视图,当我尝试显示帐户名称时会出现错误:

好的

<%= user.account_id %>

KO

<%= user.account.name %>

错误:

NoMethodError in Users#index
undefined method `name' for nil:NilClass

<tbody>
             <% @users.each do |user| %>
               <tr>
                 <td><a href="/accounts/<%= user.account_id %>"><%= user.account.name %></a></td>

【问题讨论】:

  • 您的一些用户没有关联帐户
  • 错误提示帐户为 nil。你能发布你声明belongs_to和has_many关系的模型吗?
  • 其中一个用户没有账号,就这么简单。
  • @Lut - 惯用方式是user.account &amp;&amp; user.account.name

标签: ruby-on-rails ruby ruby-on-rails-4 associations


【解决方案1】:

抛出错误是因为有一些 users 没有关联的 account

如果您使用的是Rails 3

 <%= user.account.name if user.account.present? %>

如果您使用的是Rails 4

<%= user.account.try(:name) %>

【讨论】:

  • #try 适用于 Rails 2.3.2。从 Rails 4.0.2 开始,它返回nil 用于现有对象上的未知方法
【解决方案2】:

name 被应用于account,它抱怨accountnil

您会发现对于@users 中的一位用户,user.account_id 有效,但返回nil(将在浏览器中显示为空白)或没有@987654328 的ID @记录。

如果用户不是要求拥有帐户,您应该改用 user.account.try(:name)。 (#try 类似于#send,但nil.try 返回nil。)

更新:实际上,由于整个表格单元格是帐户的链接,请尝试以下操作:

<td>
  <% if user.account %>
    <%# user.account definitely exists if you get into this block. %>
    <%= link_to user.account.name, user.account %>
  <% end %>
</td>

【讨论】:

  • 喜欢尝试!尝试(如果您执行 user.account.try(:badassroflcopter),try 也会返回 nil)
  • 视情况而定。在这种情况下,期望user.account 或者is_a? Account== nil 应该是合理的,仅此而已;所以坚持! 版本(在这种情况下)可能有点迂腐。
  • 在上下文中可以合理地假设,但是我仍然希望受到保护以防止 name 方法/列被重命名。无论如何,这是尝试/发送之间的另一个区别
【解决方案3】:

您需要在控制器中定义@users。我没有看到你的控制器,但我假设是这样的:

def index
 @users = User.all
end

错误告诉您名称返回“nil”。每个用户都有一个 account.name 吗?我将首先添加 rescue nil %> 并查看是否显示任何帐户名称。

【讨论】:

  • 为什么会被否决?明确的答案是其中一个 account.name 调用是 nil,因此它没有调用任何内容,需要救援。
  • 如果没有分配@users 变量,它将是undefined method each for nil。返回 nil 的不是 name,而是 nil 是 user.account。因为有异常而添加异常处理程序不是解决办法,它是一种隐藏真正问题的方法。
  • 你刚才说的就是我刚才说的。请求的记录不存在,因此除非您希望代码中断,否则如果其中一个用户记录没有关联,则需要有一种方法来挽救。
  • 你写了the error is telling you that name is returning 'nil'- 这不是真的。错误是说您试图在未定义该方法的nil 对象上调用方法namename 不会返回任何内容,因为它从未被调用过。
  • The requested record is not there ...但其余记录都在那里。问题不在于@users作为一个整体,只有与其中之一。
猜你喜欢
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多