【问题标题】:Find by include nil object error in rails通过在 rails 中包含 nil 对象错误查找
【发布时间】:2010-12-27 03:33:18
【问题描述】:

我一直在努力解决这个问题,但我真的不知道发生了什么。我有一小段代码:

DiscoveredLocation.find_by_user_id(user.id, :include => [:boss_kills])

模型是:

DiscoveredLocation(id, user_id, boss_location_id)
BossKill(user_id, monster_id)

和关联:

Monster belongs_to :boss_location
Monster has_many :boss_kills

BossKill belongs_to :user
BossKill belongs_to :monster


DiscoveredLocation belongs_to :user
DiscoveredLocation  belongs_to :boss_location

DiscoveredLocation  has_many :monsters, :through => :boss_location

DiscoveredLocation  has_many :boss_kills, :through => :monsters

当我执行 find_by 时出现此错误:

NoMethodError in BossesController#index

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

如果我将包含选项更改为任何其他模型,例如 :monster,它会很好用。我几乎被这个问题所拥有:P。也许有人可以帮助我? :)

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    DiscoveredLocation 模型试图通过关联定义嵌套的 has-many:

    DiscoveredLocation  has_many :monsters, :through => :boss_location
    DiscoveredLocation  has_many :boss_kills, :through => :monsters
    

    我不相信 ActiveRecord 可以开箱即用。有一个 nested_has_many_through 插件声称支持这一点——我不知道它是否适用于这种情况。

    更多讨论可以在herehere找到

    【讨论】:

    • 这听起来很有趣。我正在仔细研究,很快就会报告我的发现。
    • 嗯,我安装了插件,仍然得到同样的错误。再想一想,我认为 Rails 应该默认支持这种关联。一个 found_location 有很多 boss_kills,并且由于一个 monster 有很多 boss_kills,所以一个 found_location 具有相同的 boss_kills 通过 monster。这看起来像使用 :through 的标准连接,不是吗?我在 BossLocation 模型上做同样的事情,它工作正常。我有 BossLocation > has_many :users, :through => :discovered_locations。这可能是关联的设置方式:/
    • 不,据我了解,不支持嵌套 has_many :through 关联。您有三个关联——belongs_to :boss_location,然后是两个链接在一起的has_many :through 关联。 IMO 最好的选择是使用 boss_kills 关联上的 :finder_sql 选项并自己编写查询。
    【解决方案2】:

    我可能是错的,但是为了帮助你,试试DiscoveredLocation.find_by_user_id(user.id, :include => [:boss_kill])

    最后,您确定要将一个名为 user 的变量传递给控制器​​吗?可能是 current_user,如果您使用的是流行的身份验证 gem?

    【讨论】:

    • 此更改导致找不到名为“boss_kill”的关联,所以我想 boss_kills 没问题。另外,是的 user 实际上是 current_user :) 在这种情况下它被称为 user 因为它在一个函数中并且 user.id 肯定是正确的(我检查了 nil 并使用 :include=>:monsters 和其他包含没有问题)。
    • 那么传递用户的函数是什么,因为它显示为空白。或者你可能有一个关于捏造作品的空白记录。奇怪的事情发生了。如果它在另一个函数中,我想查看整个函数。谢谢。
    • 肯定不是用户的问题。但是仅供参考,就像: def self.getLocationNextBosses(user) DiscoveredLocation.find_all_by_user_id(user.id, :include => [:boss_location, :monsters]) end 并且 getLocationNextBosses 以 current_user 作为参数被调用。
    【解决方案3】:

    您还需要包含中间表,否则无法将 boss_kills 映射到 DiscoveredLocations:

    DiscoveredLocation.find_by_user_id(user.id, :include => [:monsters, :boss_locations,:boss_kills])
    

    此外,请检查您的开发日志以查看生成的查询。如果可能,请在此处发布,以便我们确定它是否缺少中间表之一。

    【讨论】:

    • 还是同样的错误。我认为“has_many :boss_kills, :through => :monsters”对于这个映射来说已经足够了。
    • 对您的数据模型有一个小误解 - 更新答案,尝试一下。
    • 相同。我实际上尝试过很多模型。只有当我删除 :boss_kills 时,它才能与其他模型一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    相关资源
    最近更新 更多