2015-01-08 5 views
0

두 개의 ActiveRecord 관계가 있는데, rel1rel2이라고합니다. 그들은 각각 다양한 joinswhere 절이 추가됩니다.서로 다른 관계에 동일한 arel 절 체인을 적용하십시오.

각각 동일한 순서의 절을 적용하고 싶습니다. 반복하지 않으려합니다.

def without_orders rel 
    rel.joins("LEFT JOIN orders ON customers.id = orders.customer_id").where("customers.id IS NULL") 
end 

rel1 = Customer 
rel2 = Customer 

# add a bunch of clauses to rel1 
# add some other clauses to rel2 

rel1 = without_orders(rel1) 
rel2 = without_orders(rel2) 

적으로는, 내가 별도의 함수로 without_orders이없는 것 :이 작업을 수행하는

한 가지 방법은 기능을하는 것입니다. 나는 어쨌든 joinswherefunc에 국한 시켜서 rel1rel2에 적용 할 것입니다.

그럴 수 있습니까? 그렇지 않다면 올바른 접근 방법은 무엇입니까?

scope :without_orders, -> { joins("LEFT JOIN orders ON customers.id = orders.customer_id").where(customers: { id: nil }) } 

을 그리고 당신은 다른 범위와 함께 체인 수 있습니다

답변

1

당신은 inidivual 범위에 그들 모두를 만들 수 있습니다.

include CustomerRelated 

그리고 당신은 어떤의 범위를 다음과 같이 사용할 수 있습니다

Customer.without_orders.where(foo: bar) 
1

이는 activesupport 우려하여 모델에서 다음

# app/models/concerns/customer_related.rb 

module CustomerRelated 

    extend ActiveSupport::Concern 

    module ClassMethods 

    def whithout_orders 
     joins("LEFT JOIN orders ON customers.id = orders.customer_id").where("customers.id IS NULL") 
    end 

    end 

end 

그리고 좋은 후보입니다 당신은 그것을 포함 우려가있는 모델

Rel1.without_orders 

또는

Rel2.without_orders 
+0

감사합니다. 에반 바이크가 제안한 것보다이 접근법에 이점이 있습니까? –

+0

이것은 모델간에 유사한 기능을 추가하는 표준 방법입니다. – Swards

+0

나는 그 이점 때문에 당신의 대답을 upvoted했지만 더 적은 코드를 필요로하고 논리가 모델에 국부적으로 유지되어 더 자연 스럽기 때문에 다른 하나를 받아 들인 것으로 표시했다. 스코프는 모델을 통해 공유해야 할 수도 있지만 일반적이지는 않습니다. –