연결 가능한 ActiveRecord 객체 반환 선호
Post.includes(:comments)
.where(published: true)
.where(author: Current.user)
.order(:name)
이 강점을 활용하고 코드에 유연성을 제공하려면 데이터를 쿼리할 때 항상 연결 가능한 개체를 반환하도록 하세요.
용법
애플리케이션이 커짐에 따라 복잡한 쿼리를 추출하는 것이 일반적입니다.
class SpecialOffer
def self.find_eligible_products(store, shopper)
return [] if store.restricted?
store.products
.where('price >= ?', 100)
.select{ |p| shopper.can_order?(p) }
end
end
@products = SpecialOffer.find_eligible_products(store, shopper)
#=> [#<Product:0x00007fb1719b7ec0>, #<Product:0x00007fb174744de8>, ...]
이 코드는 작동할 수 있지만 특정 방식으로
@products
를 주문해야 하는 경우 어떻게 됩니까? 아니면 추가 로직을 추가하시겠습니까? 아니면 일부 연결을 지연 로드하시겠습니까?이 경우
SpecialOffer
메서드의 반환 유형은 배열입니다. sort
및 select
와 같은 Ruby 배열 방법을 사용하도록 전환해야 하며 더 많은 데이터가 필요한 경우 실수로 N+1 버그를 도입할 수 있습니다.이 코드를 리팩토링하여 연결 가능한 객체를 반환하도록 합시다.
class SpecialOffer
def self.find_eligible_products(store, shopper)
return Product.none if store.restricted?
product_ids = store.products
.where('price >= ?', 100)
.select{ |p| shopper.can_order?(p) }
.map(&:id)
Product.where(id: product_ids)
end
end
@products = SpecialOffer.find_eligible_products(store, shopper)
#=> Product::ActiveRecord_Relation
먼저
none
쿼리 메서드를 사용합니다. 이 메서드는 비어 있지만 여전히 연결 가능한 결과를 반환합니다. 이 빈 관계에서 order
, includes
또는 where
와 같은 ActiveRecord 메서드를 호출할 수 있으며 단순히 결과를 반환하지 않습니다.둘째, 복잡한 제품 쿼리의 결과를 직접 반환하는 대신 올바른 제품을 수집한 다음 해당 제품
id
에 대해서만 "신선한"결과를 반환합니다. 이로 인해 추가 데이터베이스 쿼리가 발생하지만 필요에 따라 결과를 조작할 수도 있습니다.결과를 정렬하거나 연결을 로드하려는 경우 데이터베이스에서 수행할 수 있으며 계산의 일부로 실행된 기존 조건에 대해 걱정할 필요가 없습니다.
@products = SpecialOffer.find_eligible_products(store, shopper)
.includes(:variants)
.order(:price)
@products = SpecialOffer.find_eligible_products(store, shopper)
.joins(:sales)
.where("sales.count > 15")
.order(:sku)
저는 이 패턴이 데이터를 올바른 모양으로 마사지하는 유연성을 유지하면서 복잡한 쿼리를 추출하는 데 매우 유용하다는 것을 알았습니다.
추가 리소스
레일스 API: ActiveRecord::QueryMethods#none
레일스 문서: Active Record Query Interface
Reference
이 문제에 관하여(연결 가능한 ActiveRecord 객체 반환 선호), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/swanson/prefer-returning-chainable-activerecord-objects-60p텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)