0

私には何人かのプレーヤーがいて、プレーヤーには取引状態があります。「アクティブ」や「非アクティブ」などの取引状態をハードコードしてから文字列を探しに行かなければならないのではなく、プレイヤーが trade_state_id (プレイヤーは一度に 1 つの取引状態)。

ここで、名前付きスコープを使用してから「Player.active」と言うと、すべてのアクティブなプレーヤーを取得できると便利です。そのためには、「アクティブ」に一致する TradeState レコードの ID を取得する必要があるため、Player クラスで次のように考えました。

named_scope :active, :conditions => {:trade_state_id => TradeState.active.first.id}

これは、スクリプト/コンソールでテストすると魅力的に機能しますが、テストに行くと機能しません。私は RSpec を使用していますが、それは関係ないと思います。最も単純なテストを実行すると、次のエラーが発生します。

「誤って 4 になる nil の id と呼ばれる」

私の知る限り、テスト フレームワークはモデルをアルファベット順に読み込んで解析しています。フレームワークは Player モデルの named_scope 呼び出しを解析し、アクティブな最初の TradeState レコードの ID を忠実に検索します。ただし、そのモデルはまだ処理されておらず、準備ができていないため、nil の ID の取得に関するエラーが発生します。

最初は、trade_states テーブルにレコードがなかったのではないかと思ったので、before(:each) ブロックで必要な trade_states を作成して保存しましたが、うまくいきませんでした。それで、いくつかのフィクスチャを作成してロードしようとしましたが、うまくいきませんでした。

これはもっともらしいと思いますか?他の説明はありますか?回避策はどうですか?TradeState オブジェクトのモックを試すことができるので、やってみます。

お時間をいただき、誠にありがとうございました。

4

3 に答える 3

0

残念ながら、これらの提案はすべて非常に優れていましたが、テストケースを実行するときに確実に機能するものはありませんでした。最初はこのコードをすべて取り消しましたが、作成しなければならなかったコードはあまり魅力的ではなかったため、問題を再考し始めました。

トレード状態ごとにプレイヤーを検索するので、トレード状態の数値列にインデックスを付けることが明らかに優先されます。ただし、定義された貿易状態はごくわずかであり、定義された貿易状態に大きな変動が生じる可能性は低いため、貿易状態がテーブルである必要があると言ったことは何もありません。

そのため、TradeStateをそれ自体でクラスにし、ActiveRecordから派生しなくなり、必要な定数を定義しました。

あなたの考えと解決策をありがとうございました。

于 2009-11-14T22:34:32.057 に答える
0

あなたが言及したこのコードは、プレーヤーが「ロード」されたときに実行されます。そのため、before(:each) ブロックでセットアップ データを作成しても、このモデルはその前にロードされている可能性があります。問題を解決するには、次のようなことを試すことができます。

named_scope :active, lambda { {:conditions => {:trade_state_id => TradeState.active.first.id} } }

これにより、named_scope を呼び出すたびに TradeState.active が呼び出されるようになります。

しかし、あなたは を呼び出すことによって何を達成していますかTradeState.active.first。代わりに、この素​​敵な方法でそうすることができます

:conditions => {:trade_state_id => TradeState::ACTIVE}

TradeState モデルに次のコードを追加します。

class TradeState < ActiveRecord::Base
  def self.const_missing(sym)
    const_set(sym, find_by_name(sym.to_s))
  end
end
于 2009-11-13T09:14:51.410 に答える
0

これは実際には潜在的に「予想される」結果です。アクティブなプレーヤーがいない場合は、

TradeState.active

は空なので、

TradeState.active.first

ゼロです、

したがって

TradeState.active.first.id

Object::idnil オブジェクトを呼び出します。

あなたは試すことができます:

TradeState.active.empty? ? 0 : TradeState.active.first[:id]

どのような場合でも、結合のために存在することを確認するためだけに、trade_states を必ず含めてください。

于 2009-11-13T22:24:20.273 に答える