2014-10-21 5 views
0

주문에는 많은 LineItem이 있습니다. LineItem에는 'car'와 같은 이름이 있습니다. 일부 패턴과 일치하는 이름을 가진 광고 항목이있는 모든 광고 주문을 찾고 싶습니다.쿼리에 관계가 포함 된 경우 포함 된 테이블에서 패턴 일치를 사용하려면 어떻게해야합니까?

예를 들어 LineItem.where('name ~* :pat', pat: 'car')을 할 수 있음을 알고 있습니다.

나는 또한 내가

Order.where.not(state: "cancelled") 
    .includes(:line_items) 
    .where(line_items: { name: "car" }) 

나는 두 개의 쿼리를 결합하기위한 구문에 대한 확실하지 않다 할 수있는 것을 알고있다. 내가 상상하는 것,

Orders.where.not(state: 'cancelled') 
     .includes(:line_items) 
     .where(line_items: ['name ~* :pat', pat: 'car']) 

이것은 매우 까다 롭습니다.

참고 : 마지막으로 레일스 activerecord에 대한 질문이 있었지만이 솔루션의 일부는 SQL을 검사하는 것이 었습니다. 그러나이 경우 include 메소드를 사용하면 무서운 SQL이 발생합니다. 좋은 결과를 얻으려면 레일즈 콘솔에

Order.includes(:line_items).where(line_item: { name: "car"}).to_sql 

과 같이 시도해보십시오!

참고 :이 질문의 제목과 관련하여 도움이 필요합니다. 이런 당신이 그것을 해시 통과 할 때에만 작동합니다 사용

rails guide에서 언급 한 바와 같이

답변

0

,

. 는 SQL-조각을 위해 당신이 조인 된 테이블 강제로 참조를 사용할 필요

내 경우에 따라서
Post.includes(:comments).where("comments.visible = true").references(:comments) 

를 쿼리는 다음과 같습니다

Orders.where.not(state: 'cancelled') 
     .includes(:line_items) 
     .where('line_items.name ~* ?', 'car').references(:line_items) 

이 광고 항목의 이름을 갖는 모든 주문을 반환 주어진 정규식과 미리로드 된 광고 항목을 일치시킵니다. 광고 항목을 미리로드하지 않으려면 includes 대신 joins을 사용하십시오.

조건에 관계없이 각 광고 주문의 모든 광고 항목을 미리로드하려는 경우 어떻게해야 할 지 잘 모르겠습니다 (그러나^o^// 할 필요는 없습니다).

편집 : this article 정확히 무슨 일이 일어나고 있는지, 그리고 내 두 번째 질문에 대답했다. 사용할 모든 광고 항목을 미리로드하려면 ... preload ha! 다시 여기 .includes를 사용하는 경우

Orders.where.not(state: 'cancelled') 
     .joins(:line_items) # note the joins 
     .where('line_items.name ~* ?', 'car').references(:line_items) 
     .preload(:line_items) 

, 당신은 dissapointed하게 될 것입니다. preload이어야합니다. 이 쿼리는 원하는 주문을 가져오고 주문을 필터링하는 데 사용 된 정규식과 일치하는지 여부에 관계없이 모든 광고 항목을 미리로드합니다.