Wednesday, December 12, 2012
One plus N (1+N) Query Problem
See Documentation for Eager Loading solution.
However, there are cases that are hard to Eager Load. One example is:
@leavetype_ids = Leavetype.pluck(:id)
for user in User.all
for lt in @leavetype_ids
user.leave_credits.with_lt_id(lt).first_or_initialize
end
end
scope :with_lt_id, ->(lt) {where(:leavetype_id => lt)}
That's a no-no, a query inside a loop is a heavy procedure. Instead, load them (via includes) and use array methods.
@leavetype_ids = Leavetype.pluck(:id)
for user in User.includes(:leave_credits)
for lt in @leavetype_ids
x = first_with_lt_id(lt,user.leave_credits)
x ||= user.leave_credits.new(:leavetype_id => lt)
end
end
def first_with_lt_id(lt,coll); coll.select{|c| c.leavetype_id == lt}.first; end
where :select_lt_id is a Array.select method.
EDIT 20121218: Eager loaded the problem but use :select_lt_id still
@users = User.includes({:leave_credits => [:leave_applications, :leavetype]}, :leave_banks, :department)
Subscribe to:
Posts (Atom)