2016-11-22 3 views
1

をスコープを組み合わせることで、私はこの3つのスコープ考えてみましょう:Railsの4 - DRY的に

scope :assembly_reclamation, -> { where(status: 5) } 
scope :customer_reclamation, -> { where(status: 9) } 
scope :wrong_delivery,  -> { where(status: 12) } 

は、今の私は、これらの3つのカテゴリーに参加する範囲を作りたいとしましょう。私はこれを今のようにしています:

scope :returnable, -> { where(status: [5, 9, 12]) } 

これは機能しますが、いくつかの欠点があります。 3つのカテゴリのうちの1つの条件を変更する場合は、それらをすべて含む範囲も再作成する必要があります。

scope :returnable, -> { assembly_reclamation.or.customer_reclamation.or.wrong_delivery } 

しかし、これは有効なコードではありません。このような

何かがよりDRYようです。

このような方法でコードを作成する方法はありますか?

UPDATE

私はカテゴリとIDを使用した例を使用している知っているが、それについて、それをしないでください。それは、スコープをマージすることに関するものです。

UPDATE 2 誰もがidの問題に集中していたので、私は、statusidから属性の名前を変更している、とあなたが本当にあるならば、それは質問

+0

http://stackoverflow.com/questions/6686920/activerecord-query-unionあなたは – Ilya

+0

ハードコーディングデータベースはIDを生成することができますあなたのアプリケーションコードに組み込むことは悪い考えです。主に、すべてのレコードを同じ順序でデータベースに挿入する必要があるため、テストには適していないためです。 – max

+1

また、スコープは単なるクラスメソッドであることに注意してください。あなたが書いているものがラムダブロックに収まらない場合は、それを通常のクラスメソッドにリファクタリングする必要があります。 – max

答えて

1

のポイントではありません

class Category 
    ASSEMBLY_RECLAMATION_ID = 5 
    CUSTOMER_RECLAMATION_ID = 9 
    WRONG_DELIVERY_ID  = 12 
    RETURNABLE_IDS   = [ASSEMBLY_RECLAMATION_ID, CUSTOMER_RECLAMATION_ID, WRONG_DELIVERY_ID] 
end 

あちこち:category_idsを扱う、それはあなたがCategoryモデルに定数としてこれらのIDを持っている場合、コードを読み取る誰のためのより有意義になります今ではスコープ内でこれらの定数を使用でき、スコープの実装ではなく定数のみを変更できます。

P.S. Rails 5 added OR supportですが、アップグレードするまではそれほど関連性がありません。次のようにいくつかのスコープを組み合わせること

EDIT

一つの方法は次のとおりです。

scope :returnable, lambda { 
    where(id: assembly_reclamation.ids + customer_reclamation.ids + wrong_delivery.ids) 
} 
+0

これは単なる例でした。私はスコープをマージする方法を探していました。範囲の基準に何かがある場合、IDを検索するだけではなく、もっと多くのものを追加することができます。 –

+0

@EnriqueMorenoTentは答えを –

+0

編集しました。問題は解決しません。それはまだその基準を満たすために使用されたロジックに依存しています(単に 'id'を満たすこと以外にもあり得る) –

関連する問題