복붙노트

[RUBY-ON-RAILS] Rails.cache.fetch와 액티브 레코드 쿼리를 캐싱 혼란

RUBY-ON-RAILS

Rails.cache.fetch와 액티브 레코드 쿼리를 캐싱 혼란

내 버전입니다 :

내 ENV는 다음과 같습니다

언제 작성 :

 Rails.cache.fetch(key) do
     User.where('status = 1').limit(1000)
 end

사용자 모델은 캐시 할 수 없습니다. 내가 사용하는 경우

 Rails.cache.fetch(key) do
     User.all
 end

그것은 캐시 할 수 있습니다. 어떻게 쿼리 결과를 캐시에?

해결법

  1. ==============================

    1.그 이유는 때문이다

    그 이유는 때문이다

    User.where('status = 1').limit(1000)
    

    실제로 범위가 아닌 쿼리 인 액티브 :: 관계를 반환합니다. 캐시에게 범위를 레일.

    쿼리를 캐시하려는 경우, 당신은이 #all로, 마지막에 쿼리 방법을 사용해야합니다.

    Rails.cache.fetch(key) do
      User.where('status = 1').limit(1000).all
    end
    

    이 액티브 객체를 캐시에 좋은 아이디어 결코 것을 바랍니다 참고. 객체를 캐시함으로써 일관성 상태 및 값을 초래할 수있다. 해당되는 경우 당신은 항상 기본 개체를 캐시한다. 이 경우, ID를 캐시하는 것이 좋습니다.

    ids = Rails.cache.fetch(key) do
      User.where('status = 1').limit(1000).pluck(:id)
    end
    User.find(ids)
    

    이 경우에 항상 실행 것 User.find에 전화를 그렇게 주장 할 수 있습니다. 그것은 사실이지만 기본 키를 사용하여 쿼리 빨리 그리고 당신은 내가 전에 설명하는 문제를 주변에 얻을. 또한, 캐시 액티브 레코드 객체는 비쌀 수 있습니다 당신은 신속하게 하나의 단일 캐시 항목 모든 Memcached가 메모리를 작성 끝낼 수 있습니다. ID를 캐시하면뿐만 아니라이 문제를 방지 할 수 있습니다.

  2. ==============================

    2.선택한 답변에 추가 : 레일 4+ 당신은 범위의 결과를 얻는 대신 모든 부하를 사용해야합니다.

    선택한 답변에 추가 : 레일 4+ 당신은 범위의 결과를 얻는 대신 모든 부하를 사용해야합니다.

  3. ==============================

    3.Rails.cache.fetch는 정확히 어떤 블록 평가합니다 캐시합니다.

    Rails.cache.fetch는 정확히 어떤 블록 평가합니다 캐시합니다.

     User.where('status = 1').limit(1000)
    

    캐시 도착 무엇 즉, 쿼리 바로 액티브 :: 관계 개체, 그래서 그냥 범위는 아니지만 그 결과 (쿼리가 아직 실행되지 않았기 때문에).

    당신은 캐시 할 유용한 무언가를 원하는 경우에, 당신은 수행하여, 예를 들어, 블록 내부 쿼리의 실행을 강제 할 필요가

    User.where('status = 1').limit(1000).all
    

    참고 레일 4, 모든 관계의 로딩 강요하지 않습니다 - 대신 사용 to_a을

  4. ==============================

    4.사용

    사용

    User.where("status = 1").limit(1000).all
    

    작동합니다.

  5. from https://stackoverflow.com/questions/11218917/confusion-caching-active-record-queries-with-rails-cache-fetch by cc-by-sa and MIT license