日別アーカイブ: 2012 . 4 / 20

Ruby on Rails 3.2.0 ActiveRecordを継承したクラスのサブクラスでtable_nameが指定できない:解決編

前回の記事で紹介した問題ですが、解決策を見つけたので書きます。

何のことはないです。継承がダメなら委譲ってことで無理やり。。

まず継承はあきらめて普通にサブクラス(だったやつ)はActiveRecord::Baseを継承します。

class B < ActiveRecord::Base
end

でスーパークラス(だったやつ)はmoduleにします。

module A
end

それをBでincludeします。

class B < ActiveRecord::Base
include A
self.table_name = “b”
end

で、belongs_toとかの設定をAにメソッド定義します。

module A
def self.initialize_me(active_record)
active_record.belongs_to :hoge
#…
end
end

最後にBから呼び出します。

class B < ActiveRecord::Base
include A
self.table_name = “b”
A.initialize_me(self)
end

あとは普通のMix-inを使って共通メソッドなりを定義していくだけです。
そもそも私、継承よりも委譲派だった。

ややこしや。

Ruby on Rails 3.2.0 ActiveRecordを継承したクラスのサブクラスでtable_nameが指定できない

3.1はできるらしいですが、3.2ではできないらしいです。

class A<< ActiveRecord::Base
end

class B << A
table_name = “bs”
end

とすればBで使われるテーブルはbsになるはずですが、superクラスの設定のまま。

調べてみると同様の現象に困っている人がいました。

これが私の勘違いでなければオライリーの「エンタープライズRails」にあるポリモーフィズムの代わりに継承を使うという部分(P.128)が実現不可能になるということではないでしょうか。

前述の記事でも話されているように「何で継承なんてしたいの?」と言っている人もいますが、オライリーの本に書いてあるようなことをしたいわけですよ。他にもいろいろと継承の多重継承にはメリットがあります。
ActiveRecordは継承の多重継承するなということなのか、またはRailsのバグなのか。。

とにかく別の方法でやりたいことを実現するように方向転換を余儀なくされました。

いくら設計してもこういうことがあるからなぁ。。

 

追記(同日)解決編