0

在我的 rails 应用程序中,我有一个User模型,其方法名为price_tier

def price_tier
  Spree::PriceTier.by_code[read_attribute(:price_tier)]
end

但是,当我有一个集合@users并一个一个调用 price_tier 时,它将PriceTier为每个实例加载查询,这会导致 N+1 问题。

includes不在这里工作,因为它不是一个协会。

@users.map { |user| user.price_tier }

有没有办法修改修复 N+1 问题的代码?

4

1 回答 1

1

您确实应该直接设置模型之间的关系,例如user has_one :price_tier. 这将使这里的代码变得轻而易举。

如果您不这样做,那么您将跳过一些应该简单的事情。您也许可以使用以下内容,尽管它仍然远不如直接关系有效:

tiers = Spree::PriceTier.where(code: @users.pluck(:price_tier))
                        .each_with_object({}) { |tier, hash| hash[tier[code]] = tier }

@users.map { |user| tiers[user.price_tier] }

注意以上假设删除实例方法:price_tier并使用属性。

我不确定是否真的值得包括上述内容-您收集用户的 price_tier,为层点击数据库(仅一次,而不是为每个用户),遍历它们以创建快速访问的哈希,然后迭代通过用户来映射这些。对于通过建立关系很容易解决的事情来说,这是很多工作。

希望这会有所帮助,并且真的希望上面的语气可以正常 - 基本上意味着你可以做类似上面的事情,尽管真正的建议是:请不要,在这里建立关系并使用传统方法:)

于 2018-10-29T09:32:27.990 回答