我正在尝试构建一个包含许多组件的产品模型。某些组件是可选的,取决于用户是否选择启用它们。 我有两个模型,一个是配置,另一个是元素(该配置)。
在开始时,我将带来数组的所有元素,然后创建另一个默认显示的数组。 但是当我编写下面的代码时,尽管两个对象都是哈希数组,但它给了我一个错误。
所以我带来了我所有元素的第一个数组:
irb(main):252:0* @all = Configuration.find(1).elements
=> [#<Element id: 1, name: "elem1", quantity: 1, position: 1, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 2, name: "elem2", quantity: 2, position: 2, subposition: 1, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 3, name: "elem3", quantity: 3, position: 2, subposition: 2, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 4, name: "elem4", quantity: 4, position: 3, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>]
然后我过滤到只有那些具有子位置nil或1
的那些irb(main):253:0> @default = @all.where(:subposition=>nil).concat(@all.where(:subposition=>1))
=> [#<Element id: 1, name: "elem1", quantity: 1, position: 1, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 4, name: "elem4", quantity: 4, position: 3, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 2, name: "elem2", quantity: 2, position: 2, subposition: 1, created_at: nil, updated_at: nil, configuration_id: 1>]
到目前为止,如此好,正如你所看到的,Elem3没有出现在@default,因为它不符合要求。
当我尝试使用数组时,问题出现了,因为我需要执行某些操作。
irb(main):257:0> @all.where(:position =>1)
=> [#<Element id: 1, name: "elem1", quantity: 1, position: 1, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>]
但@default中的相同操作将失败,
irb(main):258:0> @default.where(:position =>1)
NoMethodError: undefined method `where' for #<Array:0x2641660>
现在,它们都是哈希数组并且看起来一样,为什么在第二种情况下同样的方法失败了呢?
非常感谢你的帮助!
答案 0 :(得分:1)
在整个代码中,@all
是ActiveRecord::Relation
,而不是数组。这使您可以执行标准.where
调用(以及其他调用)。当您分配到@default
时,您使用了.concat
来评估查询并将实际数组分配给@default
。
您可以在第二个代码块中尝试不同的方法。也许是这样的:
@default = @all.where("subposition is null or subposition = ?", 1)
答案 1 :(得分:0)
好吧,你的问题是concat将一个集合转换为一个数组。
我会替换:
irb(main):253:0> @default = @all.where(:subposition=>nil).concat(@all.where(:subposition=>1))
由:
@default = @all.where("subposition = '1' OR subposition = nil") #I'm unsure of the nil in the statement, I nerver remember, try NULL if it fails
这样,您只进行一次数据库查询并保留ActiveRecord集合。
因此,您将能够将其他条件链接在其上。