0

基本的な関連付けの設定 (Customer は Person モデルの拡張であることに注意してください):

Customer has_many :orders
Order belongs_to :customer

Customer.rb 内には、次のクラス メソッドがあります。

# SCOPE
def self.ordered_in_90_days
  joins(:orders).where('orders.created_at > ?', 90.days.ago)
end

私のテストでは、次のコードで新しい Order を作成し (FactoryGirl に対する顧客感謝を自動的に作成します)、次に上記で定義した Customer モデルの self メソッドを使用します。

it "finds customers who have ordered within the last 90 days" do
  @order     = FactoryGirl.create(:order, created_at: 50.days.ago)
  @customer  = @order.customer

  Customer.count.should == 1  #passes
  Order.count.should == 1     #passes

  puts Customer.all.to_yaml   #for debugging, see below
  puts Order.all.to_yaml      #for debugging, see below

  Customer.ordered_in_90_days.should == [@customer]   #fails! returns: []
end

顧客と注文の両方が作成されていますが、メソッド呼び出しで何も返されていません (空の配列)。私は何が欠けていますか?

工場に関する追加情報を次に示します。

FactoryGirl.define do
    factory :customer do
        first_name "Wes"
        last_name "Foster"
        type "Customer"
    end

    factory :order do
        customer
    end
end

Customer と Order のデバッグ出力は次のとおりです (Customer は Person の拡張であるため、customer_id ではなく person_id が表示されることに注意してください)。

---
- !ruby/object:Customer
  attributes:
    id: 1
    first_name: Wes
    last_name: Foster
    type: Customer
    created_at: 2013-09-16 21:54:26.162851000 Z
    updated_at: 2013-09-16 21:54:26.162851000 Z
    middle_name: 
---
- !ruby/object:Order
  attributes:
    id: 1
    person_id: 
    created_at: 2013-07-28 21:54:26.135748000 Z
    updated_at: 2013-09-16 21:54:26.192877000 Z

(お客様

4

1 に答える 1

1

デバッグ出力は問題を示しています。Order inspect を見てください: person_id が空白になっています。

まず、 Customer が Person のサブクラス/拡張であっても、 Orderは ActiveRecord にではなくbelongs_to :customerを探すように指示します。Order モデルでデフォルト以外の方法で関連付けを構成する必要があることを示していますか?customer_idperson_id

そうしないと、 Order ファクトリでエイリアス化された関連付け参照を誤って処理している可能性があると思います。私は自分のプロジェクトで factory_girl 関連付けエイリアス参照を使用していません — 私は関連付けを自分のファクトリから遠ざけようとしています — しかし、factory_girl のドキュメント: Association Aliasesであなたの方法論を検証します。

私は個人的に、あなたのテスト例でこれを試してみます:

it "finds customers who have ordered within the last 90 days" do
  @customer  = FactoryGirl.create(:customer)
  @order     = FactoryGirl.create(:order, created_at: 50.days.ago, customer: @customer)

  Customer.count.should == 1  
  Order.count.should == 1     

  Customer.ordered_in_90_days.should == [@customer]
end

例で @order.customer を明示的に設定すると、工場の依存関係と複雑さを排除できます。

サイドノート
アソシエーション エイリアス メソッドをファクトリに保持し、他のテストでそのアソシエーションに依存する場合は、ファクトリ リレーションシップが正しくインスタンス化されていることを確認する別のテストを作成することをお勧めします。

@order = create(:order)
expect(@order.customer).to be_a(Customer)

またはそのようなもの...

于 2013-09-16T22:13:00.740 に答える