我有一个模型Item,它使用单表继承实现,共有三种类型。Item具有树结构,该结构使用has_many:through关系表示父级(称为组)和子级(称为sub_items)。一个子类(我们将其称为ItemA)在任何时候都必须只有一个父类(但其他子类可以有0个或多个父类)。我不知道如何实施验证来强制执行树层次结构的规则,因此我将其遗漏了。
ItemA有一个辅助方法parent
,以获取其父对象。有时这种方法会提出来undefined method 'first' for nil:NilClass
。它并不总是发生,但在某些情况下会发生。
我正在使用jqGrid列出所有ItemAs。我对某些列(包括父列)使用了排序功能。网格最初将成功加载ItemA,表明它们全都具有应有的父项。但是,当我尝试对父列进行排序时,我会收到错误消息,好像它们突然消失了一样。当我includes(:groups)
从排序方法中删除时,它消失了。我不知道为什么会有帮助,但我认为问题已解决。直到...
我正在用Rspec,Factory Girl和Selenium测试我的应用程序。在我的测试之一中,我parent
在使用Factory Girl创建的ItemA实例上调用该方法。它引发了错误。我parent
间接使用该方法的测试不会失败。例如,该parent
方法在ItemA的索引页面上被调用,并且许多测试毫无问题地访问了该页面。这种情况尚未解决。我的应用程序不再有对的调用includes
,因此这次不属于该应用程序。
项目A
class ItemA < Item
# This method is called in Situation 1
def self.sort_by_parent sort_order
all.sort_by(&:parent_name).tap do |i|
i.reverse! if sort_order == :desc
end
end
def parent
groups.take
end
def parent_name
parent.component_name
end
end
物品
class Item < ActiveRecord::Base
has_many :item_groups, foreign_key: 'sub_item_id', dependent: :destroy
has_many :groups, through: :item_groups
has_many :group_items, class_name: 'ItemGroup', foreign_key: 'group_id', dependent: :destroy
has_many :sub_items, through: :group_items
end
update_spec
feature 'ItemA editing', js: true do
given!(:item_a) { create(:item_a) }
given!(:parent) { create(:item_b) }
scenario 'when parent', focus: true do
itemas_page = ItemAsPage.visit # This is a custom page object
# Situation 2 occurs here
itemas_page.edit_parent item_a.parent_name, parent.component_name
expect(itemas_page).to have_item_a_with parent.component_name
end
end
为什么该parent
方法有时读为nil,如何使它始终产生一个值?
编辑:在更改代码时,我遇到了更多导致此错误的情况。我检查了来源。这是快照ActiveRecord::FinderMethods
:
module ActiveRecord::FinderMethods
def take(limit = nil)
limit ? limit(limit).to_a : find_take
end
private
def find_take
if loaded?
@records.first
else
@take ||= limit(1).to_a.first
end
end
end
出于调试目的,我将parent
方法修改为如下所示:
def parent
groups.tap {|g| puts '@records: ' + g.instance_variable_get(:@records).inspect }.take
end
@records
是零。我尝试将其更改groups.reload.take
为可以@records
加载,但无法正常工作。我正在使用groups.limit(1).to_a.first
,目前正在运行,但是我很想知道我的应用程序中是哪种错误导致了此问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句