11

조각 캐싱과 열정적 인로드는 적어도 때로는 다소 차이가 있습니다. 많은 의견을 갖고있는 많은 게시물을 가지고있는 사용자가 있으며, 많은 의견을 갖고 있으며 많은 의견을 가질 수 있다고 가정 해 봅시다.조각 캐싱 및 열망 로딩 : 두 가지 장점을 모두 얻는 방법?

페이지를 렌더링해야 할 때 데이터베이스를 n-1 번 누르는 것을 피하기 위해 사용자, 모든 게시물, 모든 댓글 등을 열망 할 수 있습니다. 또는 각 개체를 느리게로드하고 조각 캐시에 의존하여 데이터베이스가 새로 추가되었거나 변경된 개체 만 쿼리 할 수있었습니다. 조각 캐싱과 열망하는로드를 모두 사용하는 것은 낭비입니다. 잠재적으로 매우 복잡한 쿼리를 수행하고 작은 개체 만 사용하여 많은 개체를 인스턴스화합니다.

하지만 사용자가 여러 바가 많고 차례로 바뀌는 응용 프로그램이있는 경우 각 Foo가 모든 바 및 관련 객체와 동시에 동시에 작성되는 응용 프로그램이있는 경우에는 어떻게해야합니까? 다음은 절대로 변경되지 않습니다. 이 경우 렌더링 된 Foos에 대해 조각 캐싱을 사용하고 싶지만 모든 관련 개체가있는 새 Foo를로드해야하는 경우 열심히로드하는 것이 좋습니다. 결국 세분화 된 수준에서 조각을 캐싱하면 얻을 수있는 것이 없습니다.

이것을 수행하는 가장 좋은 방법은 무엇입니까? Foo의 ID를 얻기 위해 하나의 쿼리를 수행 한 다음 각 Foo를 렌더링해야 할 때 열심히로드하여 명시 적으로 찾을 수 있다고 가정합니다. 이것을하는 더 나은/더 우아하고/관용적 인 방법이 있습니까?

답변

0

컨트롤러에 fragment_exists? 메서드를 사용하면 모든 개체가 이미 캐시에있을 때로드하는 것을 막을 수 있습니다. 이것은 페이지가 처음 호출 될 때만 적용됩니다. 이처럼

:

뷰 사용 조각 chaching에서 다음
if fragment_exists? "my_cache_key_#{id}" 
    # load your object without eager loading here   
    else 
    # eager load your objects here   
    end 

:

<% cache("my_cache_key_#{@object.id}") do %> 
... 
... 
... 
<% end %> 

당신을 위해 무엇을해야 그!

+0

fragment_exists에 액세스하려고 시도 할 때 나타납니다. *** NoMethodError Exception : 정의되지 않은 메소드 \'fragment_exists? ' for # ' –

+0

아, 그것은 복수화하지 않고'fragment_exist?'를 원하는 것처럼 보입니다. –

0

Rails 4에 대한 @daviddb 응답을 작성하면 컨트롤러에서 MD5 해시를 다시 만들 때보기에 skip_digest이 필요하다는 것을 알게되었습니다. 또한

, 객체를 처음 찾는없이,이 마지막으로 수정 된 타임 스탬프 개체를 얻을 어려울 것이다, 그래서 그것을 도움이 .includes(:object1, :object2)

views/customers/show.html.slim (원하는 템플릿에 대한 조정없이 초기 쿼리를 수행하는 발견 엔진)

- cache['customers/show', @customer], skip_digest: true do 
    h1 
    = @customer.account.name 
    = render 'account_summary', account: @customer.account 
    = render 'account_details', transactions: @customer.account.transactions 
    ... 

controllers/customers_controller.rb

def show 
    customer = Customer.find(params[:id]) 
    if fragment_exist?(['customers/show', customer]) 
     @customer = customer 
    else 
     @customer = Customer.includes(account: :transactions).find(params[:id]) 
    end 
    end 

참고 :을 설정하여이 뷰를 변경할 때 배포 할 때 캐시를 지우고 새 레이아웃이 제대로 렌더링되도록하기 위해 의존하는 부분을 지워야합니다.

0

저는 람다를 사용하여 캐싱과 비슷한 것을했습니다. 아래에서 아이디어를 얻을 수 있습니다. 문제가 해결되면 가장 인기있는 사용자를 확보하는 것은 많은 작업을 필요로하며> 5 초가 필요합니다. 하지만 람다를 사용하면 사용자 목록을 캐시 할 수 있습니다.

controller: 
def index 
@users = -> { User.by_rating } 
end 

view: 
= cache "rating-list", expires_in: 1.day do 
    - @users.call.each do |user| 
    = render user