빠른 결론
includes는 eager_load
일수도 preload
수도 있다.
왜?
includes메소드는 특정조건에 부합하면 eager_load
와 같은 동작을 하고
부합하지 않으면 preload
와 같은 동작을 하기 때문이다.
조건은?
- includes한 테이블에 where문을 추가해 필터를한 경우
- includes한 association에 joins or references를 호출한 경우
- 임의의 association에 eager_load를 호출한 경우
위에 세조건을 or조건으로 하나만 일치해도 true가 된다.
근거는?
eager_loading?코드를 보면 알 수 있는데
eager_loading?이 true면 LET JOIN을 시키고 false일 경우 쿼리를 나눠서 읽어온다.
def eager_loading?
@should_eager_load ||=
eager_load_values.any? ||
includes_values.any? && (joined_includes_values.any? || references_eager_loaded_tables?)
end
해설1
- includes한 테이블에 where문을 추가해 필터를한 경우
references_eager_loaded_tables?는 JOIN대상 이외에 references가 실행되었을때 true가 된다.
where로 다른 테이블에 필터를 걸었을때 references가 실행되므로 where문을 추가해 필터한 경우도 체크
할 수 있다.
해설2
- includes한 association에 joins or references를 호출한 경우
joined_includes_values는 includes한 association에다가 joins도 걸어버린 애들의 리스트이다.
joined_includes_values.any?
이므로 그런 쿼리가 있다면 true처리된다.
해설3
- 임의의 association에 eager_load를 호출한 경우
eager_load_values
나 includes_values
는 eager_load했거나 includes했을때 추가되는 녀석들임