0

私は次のように設定された標準的なポリモーフィックな関係を持っています:

#Foo
has_many: bar, as: foobar

#Qux
has_many: bar, as: foobar

#Bar
belongs_to :foobar, polymorphic: true

has_many: bar, as: foobarたとえば、などの特定の属性を持つモデルを適用できるようにしたいnameので、次のようなことができます。

bar.foobar.name

その時点でどのモデルのfoobarであるかは問題ではないことを知っています。(すべてのfoobarにはname属性があるため)

これを行う方法はありますか、それともresponds_to?使用するたびにテストする必要がありますか?

4

1 に答える 1

1

FooQux拡張する基本クラスを作成することにより、デフォルトを提供できます。それ以外の

class Foo < ActiveRecord::Base
  has_many: bar, as: foobar
end

class Qux < ActiveRecord::Base
  has_many: bar, as: foobar
end

あなたは次のようなことをすることができます

class Foobar < ActiveRecord::Base
  has_many: bar, as: foobar
end

class Foo < Foobar; end

class Qux < Foobar; end

次に、を拡張するクラスで一貫性を持たせたい属性のデフォルトのアクセサメソッドを作成できますFoobar

class Foobar < ActiveRecord::Base
  has_many: bar, as: foobar

  def name
    "some default name"
  end
end

class Foo < Foobar
  def name
    "some overloaded name for Foo"
  end
end

class Qux < Foobar; end

name上記のようにオーバーロードFooするか、のように省略できQuxます。とにかく、name属性は、からのデフォルトのみであっても使用できますFoobar

foo = Foo.new
puts foo.name  # "some overloaded name for Foo"

qux = Qux.new
puts qux.name # "some default name"

他の言語で一般的であるように、インターフェースまたは抽象クラスを介してより多くのコントラクトを作成しようとしている場合、Rubyはどちらもサポートしていません。ただし、インクルードするミックスインを使用して、定義されていない場合は例外FooQuxスローすることができます。この種の実装の例をここで読んでくださいname

これらのモデルがテーブルに関連付けられた列を持つことになっている可能性に注意してください。オーバーロードされたメソッドのどこかにname組み込むことをお勧めします。上のドキュメントを参照してくださいread_attribute(:name)nameread_attribute

于 2012-11-02T18:05:07.997 に答える