Object#is_a?
Rails 3で最も奇妙な方法で失敗しています。私は単一テーブル継承を次のように設定しています(簡潔にするために簡略化)。
# resource.rb
class Resource < ActiveRecord::Base
# blah blah
end
# video.rb
class Video < Resource
# blah blah
end
私のコントローラーには、次のものがあります。
def create
@resource = Resource.find params[:resource_id]
logger.info '@resource class: ' + @resource.class.name
logger.info '@resource superclass: ' + @resource.class.superclass.name
logger.info '@resource is_a?(Video): ' + @resource.is_a?(Video).inspect
logger.info '@resource is_a?(Resource): ' + @resource.is_a?(Resource).inspect
logger.info '@resource is_a?(ActiveRecord::Base): ' + @resource.is_a (ActiveRecord::Base).inspect
# Do some other stuff
end
アクションを呼び出すと、#create
次のログ結果が生成されます。
@resource class: Video
@resource superclass: Resource
@resource is_a?(Video): true
@resource is_a?(Resource): false
@resource is_a?(ActiveRecord::Base): true
Video
インスタンスはですが、ActiveRecord::Base
ではないことに注意してくださいResource
。これは単なる学術的な関心事ではありません。アクションから呼び出されたフレームワークコードはis_a?
、型の不一致をチェックするために使用し、Video
がではないと判断したときに発生しResource
ます。
ただし、Railsコンソールでは、 is_a?(Resource)
trueを返します。
ここで何が起こっているのでしょうか?