4

単一テーブル継承を利用するカードゲームアプリケーションがあります。、、列を持つclass Cardデータベーステーブル、およびのサブクラスの数があります(引数のためにとを含む)。cardstypeCardclass Foo < Cardclass Bar < Card

たまたま、Fooはゲームの元の印刷からのBarカードであり、は拡張からのカードです。モデルを合理化するために、次のようなディレクトリ構造を作成しました。

app/
+ models/
  + card.rb
  + base_game/
    + foo.rb
  + expansion/
    + bar.rb

そして、以下を含むようにenvironment.rbを変更しました:

Rails::Initializer.run do |config|
  config.load_paths += Dir["#{RAILS_ROOT}/app/models/**"]
end

ただし、アプリがデータベースからカードを読み取ると、Railsは次の例外をスローします。

ActiveRecord::SubclassNotFound (The single-table inheritance mechanism failed to locate the subclass: 'Foo'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite Card.inheritance_column to use another column for that information.)

これを機能させることは可能ですか、それともフラットなディレクトリ構造に運命づけられていますか?

4

1 に答える 1

3

おそらくこれを行う最良の方法は、モジュールFoo内にクラスをネストすることです。BaseGame

rubyモジュールは、他の言語のパッケージ構造とほぼ同じであり、関連するコードのビットを論理グループに分割するためのメカニズムです。ミックスイン(ここで説明されています: http://www.rubyfleebie.com/an-introduction-to-modules-part-1/)などの他の機能がありますが、この場合は関係ありません。

クラスの参照とインスタンス化は少し異なる方法で行う必要があります。たとえば、次のようにクエリします。

BaseGame::Foo.find(:all,:conditons => :here)

または、次のようにインスタンスを作成します。

BaseGame::Foo.new(:height => 1)

Railsは、ActiveRecordモデルのモジュール化されたコードをサポートしています。クラスが保存されている場所にいくつかの変更を加える必要があります。たとえば、クラスFooをモジュールBaseGameに移動すると(例のように)、に移動する必要がありapps/models/foo.rbますapps/models/base_game/foo.rb。したがって、ファイルツリーは次のようになります。

app/
 + models/
  + card.rb #The superclass
   + base_game/
      + foo.rb

クラスでこれを宣言するには、次のように定義します。

module BaseGame
  class Foo < Card
  end
end
于 2010-05-26T12:59:50.317 に答える