我有一个循环,它会击中几个范围,然后将结果推送到数组中。我遇到的问题是如果没有记录匹配范围,它仍然返回 ActiveRecord :: AssociationRelation [] 。如何过滤掉这些内容,以便我不能将它们放入我的阵列中?
示例:
class Snack
belongs_to :member
scope :red, -> { where(color: 'red') }
scope :snacktypefind, -> (snacktypefind) { where(snacktype: snacktypefind) }
end
class Member
has_many :snacks
def find_snacks(snacktypes)
returnarray = []
snacktypes.each do |snacktype|
returnarray << self.snacks.red.snacktypefind(snacktype)
end
return returnarray
end
end
然后在一个视图中说我想:
<% @member.find_snacks(['bannana','orange']).each do |snack| %>
<li>snack.name</li>
<% end %>
在上面的例子中,我希望数组为[],而不是:
[#<ActiveRecord::AssociationRelation []>, #<ActiveRecord::AssociationRelation []>]
这次我做错了什么傻事?再次感谢您提供任何帮助!
答案 0 :(得分:1)
哇,你只是通过额外的代码更容易实现这个
class Member
has_many :snacks
def find_snacks(snacktypes)
snacks.red.snacktypefind(snacktypes)
end
end
这变成了
"SELECT snacks.* FROM snacks WHERE snacks.member_id = YOUR_MEMBER_ID AND snacks.color = 'red' AND snacks.snacktype IN (YOUR snacktypes array)"
目前我们将其称为“查询和推送”的实施方式存在缺陷。
首先,这将创建可能由单个对象组成的多个微型集合。这将是迭代的地狱,因为你必须嵌套迭代来实际访问对象。
其次,这将为每个snacktype
创建多个查询1,这将降低性能。
您真正想要的是链接查询方法,将所有内容缩小到只包含您需要的元素的ActiveRecord::Relation
。这将执行单个查询,当您迭代管道对象时,将是您要访问的实际对象,而不是另一个必须再次迭代的ActiveRecord::Relation
。
ActiveRecord Query Methods关于范围和查询链的重要部分是它们在链完成之前不会被执行,从而允许您以非常精细的方式轻松添加和删除条件。这样,您可以显式地定位数据库中的数据,而不是将其加载到内存中并从那里清除它。
答案 1 :(得分:0)
我最终这样做了:
def find_snacks(snacktypes)
returnarray = self.snacks.none
snacktypes.each do |snacktype|
returnarray += self.snacks.red.snacktypefind(snacktype)
end
return returnarray
end
由于 .none ,仅适用于rails 4,但我没有rails 3项目,所以我认为没关系。