2012-06-10 3 views
2

AR 연관이 있으면 모델 연관 메소드를 작성하고 그렇지 않은 경우에는이를 작성해야합니다. 첫 번째 검색 후에 데이터베이스가 다시 쿼리되지 않도록하려면 어떻게해야합니까? 아래에이 방법의 두 가지 버전이 있지만 두 가지 단점이 있습니다.메서드 내부에서 데이터베이스 호출을 반복하지 않는 가장 효율적인 방법은 무엇입니까?

이 메서드는 비효율적 일 때마다 쿼리를 수행합니다.

def cart 
    carts.order('created_at desc').where(:purchased_at => nil).first || carts.create 
    end 

이 방법은 db 검색을 한 번만 수행하지만 cart.destroy와 같은 경우 동기화되지 않습니다.

def cart 
    @cart_ || @cart_ = carts.order('created_at desc').where(:purchased_at => nil).first || @cart_ = carts.create 
    end 

답변

2

액티브 관계는 당신이 그들로부터 인스턴스를 만들 수있는 작은 알려진 기능이 있습니다

User.where(name: 'John').new #=> <User @name="John"> 

find_or_create와 그 결합하고 당신은 당신의 방법에있어 : ​​

Cart.order('created_at DESC').find_or_create_by_purchased_at(nil) 

cart 전화를 할 때마다 레일스는 쿼리를 실행합니다. q를 치기 때문에 성능이 좋습니다. 요청이 끝날 때 만료되는 uery 캐시 이 메서드 호출 사이에 모든 카트를 비우지 않는다고 가정하면 정상이어야합니다.

+0

와우, 정말 멋지다. 나는 이것과 함께 갈 것이라고 생각 하겠지만 그것이 쿼리 캐시를 치는 것인지 말할 수는 없다. – pixelearth

+0

여기를 참조하십시오 : http://pastie.org/4062197 – pixelearth

+0

* * 쿼리 캐싱은 실제 요청 중에 만 발생합니다. 'tail -f log/development.log'를 실행하고 실제 요청 중에 출력을 체크하면 캐시를 적절히 사용하고 있다면'Cart Load' 대신'CACHE'가 보일 것입니다. – coreyward

관련 문제