2

パラメータがRailsの特定のクラスのインスタンスであることを確認しようとしています:

def schedule(action, *args)
  if arg.is_a? Aircraft
    ...
  end
end

ライブラリ クラス (ファイルはlib/にあります) でこれを行っていますが、初期化されていない一定の Aircraftエラーが発生します。Aircraft はモデル クラスであり、app/modelsに対応するaircraft.rbファイルがあります。

ライブラリでモデル クラスとインスタンスを使用できますか? どのように?


エラー コンテキスト:

エラーは RSpec テストで発生します。コードはブラウザで動作します。_spec.rbファイルでモデルを要求しようとしましたが、現時点では成功しません。

4

4 に答える 4

4

Railsライブラリファイルでモデルクラスを使用でき、正確に正しい方法でそれを行っています. Rails は、クラス Aircraft が参照されたときにそれを自動ロードする必要があります。

そのため、なぜ失敗したのかを理解するには、もう少しコンテキストが必要です。Rails 環境なしで lib/ ファイルをロードしている可能性はありますか?

これを解決する 1 つの方法は、モデル ファイルaircraft.rbを明示的に要求することです。ただし、このアプローチは、Rails のオートローダーを微妙かつ驚くべき方法で破壊するため、すぐに気が狂ってしまうことに気付くでしょう。Rails は、Rails のクラス ローダーに逆らうのではなく、それを使用する方がはるかに簡単です。

アップデート

RSpec テストの場合、仕様ファイルで環境をロードするために使用しているコードを確認できますか? 次のようになります。

require File.dirname(__FILE__) + '/../spec_helper'

ファイルの先頭にある必要があります。これは、RSpec Rails プラグイン (ここ) がインストールされていることと、RSpec プラグインのデフォルトの spec/spec_helper.rb ファイルがあることの両方を前提としています。そのようなファイルがない場合は、次を実行してみてください。

ruby script/generate rspec
于 2008-11-28T19:11:29.670 に答える
3

これにより、航空機モデルにアクセスできるようになります。

require File.dirname(__FILE__) + "/../app/models/aircraft"

[編集]

ダニエルは文脈について良い点を挙げています。rakeタスクを使用している場合は、必ず環境をロードしてください。

task :my_task => :environment do
  # something happens...
end 
于 2008-11-28T18:34:01.523 に答える
1

ダニエルの答えは正しいですが、考えてみてください: ライブラリ クラスがモデル クラスを参照しているのはなぜですか? ライブラリ コードは、提供するインターフェイスについては知っているかもしれませんが、実際のモデル クラスについて知っているべきではありません。

#schedule別の考慮事項:メソッドがモデルのクラスを要求するのはなぜですか? 新しいモデル クラスが で動作する場合は、Spaceshipそれで動作#scheduleする#scheduleように変更する必要があります。それは必要ありません。

Aircraft代わりに、オブジェクトと他のクラスのオブジェクトが によって処理される方法の違いは何#scheduleですか? その違いを独自のメソッドに抽出できますか? 次に、これらの実装を各モデル クラスに移動し、分岐ではなくポリモーフィズムによってどれを使用するかを決定できます。

たとえば、以前は次のようになっていました。

def schedule(action, vehicle)
  if vehicle.is_an?(Aircraft)
    possible_days = case action
    when "travel"
      ["Mon", "Wed", "Fri"]
    when "repair"
      ["Sat", "Sun"]
    end
    possible_days.rand
  elsif vehicle.is_a?(Spaceship)
    possible_days = case action
    when "travel"
      ["Sat", "Tue", "Thu"]
    when "repair"
      ["Sun", "Mon"]
    end
    possible_days.rand
  end
end

次のようになります。

def schedule(action, vehicle)
  vehicle.days_action_can_be_performed(action).rand
end


class Aircraft
  def days_action_can_be_performed(action)
    possible_days = case action
    when "travel"
      ["Mon", "Wed", "Fri"]
    when "repair"
      ["Sat", "Sun"]
    end
    possible_days
  end
end

class Spaceship
  def days_action_can_be_performed(action)
    possible_days = case action
    when "travel"
      ["Sat", "Tue", "Thu"]
    when "repair"
      ["Sun", "Mon"]
    end
    possible_days
  end
end

新しいクラスが追加されると#days_action_can_be_performed、 を実装するだけで、 で動作し#scheduleます。

于 2011-02-23T15:37:07.243 に答える
0

これを試してみる必要があります: if arg.is_a? ::Aircraft

于 2011-02-15T05:52:31.080 に答える