只有当作用域返回记录而不是空白时,才将对象推入数组



我有一个循环,它击中几个作用域,然后将结果推入一个数组。我遇到的问题是,如果没有与范围匹配的记录,它仍然会返回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 []>]

这次我做错了什么傻事?再次感谢您的帮助!

哇,你用额外的代码让它变得更容易了,这个怎么样

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查询方法作用域和查询链的重要之处在于,在链完成之前,它们不会被执行,这允许您以非常精细的方式轻松地添加和删除条件。通过这种方式,您可以明确地将数据库中的数据作为目标,而不是将其加载到内存中并从内存中清除。

我最终做了这个:

 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项目,所以我认为这还可以。

最新更新