遇到的场景是:
@articles.each do |article|
user = User.find(article.user_id)
user.name
end
这个时候就遇到了N+1 的问题,而我的问题其实更复杂些,其中还夹杂着多个中间表(就不追叙了)
而其中的@articles 其实就那么几个 user,如果重复的使用 article.user.name 就会很恶心
我的解决的方法是:
先用一个 hash 将 已经出现过的 user 以 {user_id => user} 保存起来
然后当 一个新的 user_id 传过来的时候,判断这个 user_id 是否在 这个 hash中,如果已经存在,那么我们就可以直接使用已经存的 user对象
如果不存在 ,我们可以重新查找,将查找的user对象 继续存进去
假设 我们 有一百篇文章 ,用户 是十个 ,那么其实处理 N+1 的问题时候 就不需要 查 100次了 ,其中查找 10 次就OK了
当然 这个不适合 大部分N+1的问题
普遍的N+1 问题 可以用 includes 来解决,或者 用 has_many 来解决,
完整的代码:
def fileter_user article
@has = {} if @has.nil?
if @has.include? articel.user_id.to_s.to_sym
user = @has[articel.user_id.to_s.to_sym]
else
user @has[articel.user_id.to_s.to_sym] = User.find(article.user_id)
end
user
end