0

Itemモデルに適用する必要のあるフィルター条件がいくつかあります

 condition1_ids = get_condition1_ids   # array of ids
 condition2_ids = get_condition2_ids   # array of ids 
 condition3_ids = get_condition3_ids   # array of ids 

 items = Item.where(:condition1.in => condition1_ids) if condition1_ids
 items = items ? 
            (items.where(:condition2.in => condition2_ids) if condition2_ids) :
            (Item.where(:condition2.in => condition2_ids) if condition2_ids)

 items = items ? 
            (items.where(:condition3.in => condition3_ids) if condition3_ids) :
            (Item.where(:condition3.in => condition3_ids) if condition3_ids)

アイデアは、フィルターが設定されている場合(条件)Item、各フィルターでモデルをフィルター処理することです。AND

コードがうまく見えません。それを行うためのより効果的な方法はありますか?

4

1 に答える 1

0

次の実際のテスト コードには、いくつかの提案が含まれています。Item クラス オブジェクトから始めてコードをドライアップし、呼び出しを連鎖させてクラスをチェックすることができます。配列を使用してパラメーターをリファクタリングし、パラメーター配列を反復処理して DRY-up コードにします。私は「in」メソッドを使用することを好みます。

これにより、よりクリーンまたはよりドライなコードに関する興味深いアイデアが得られることを願っています。

アプリ/モデル/item.rb

class Item
  include Mongoid::Document
  field :condition1, type: Integer
  field :condition2, type: Integer
  field :condition3, type: Integer
end

テスト/ユニット/item_test.rb

require 'test_helper'

class ItemTest < ActiveSupport::TestCase
  def setup
    Item.delete_all
  end

  def get_condition1_ids; [1, 2]; end
  def get_condition2_ids; [2, 3]; end
  def get_condition3_ids; nil; end

  test "criteria chain" do
    Item.create(condition1: 1, condition2: 2, condition3: 3)
    Item.create(condition1: 2, condition2: 3, condition3: 4)
    Item.create(condition1: 3, condition2: 4, condition3: 5)

    condition1_ids = get_condition1_ids   # array of ids
    condition2_ids = get_condition2_ids   # array of ids
    condition3_ids = get_condition3_ids   # array of ids

    items = Item
    [
        [:condition1, condition1_ids],
        [:condition2, condition2_ids],
        [:condition3, condition3_ids]
    ].each do |condition, condition_ids|
        items = items.in(condition => condition_ids) if condition_ids && !condition_ids.empty?
    end

    result = items.class == Mongoid::Criteria ? items.to_a : nil
    p result
  end
end

レーキテスト

Run options: 

# Running tests:

[#<Item _id: 50e7b11b29daebeefd000001, _type: nil, condition1: 1, condition2: 2, condition3: 3>, #<Item _id: 50e7b11b29daebeefd000002, _type: nil, condition1: 2, condition2: 3, condition3: 4>]
.

Finished tests in 0.010446s, 95.7304 tests/s, 0.0000 assertions/s.

1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
于 2013-01-05T05:02:21.500 に答える