2

私はこのSTI実装を持っています:

class Instruction < ActiveRecord::Base
  def get_view
    return "I'm a pseudo abstract base method!"
  end
end

class SCreateWebPage < Instruction
  def get_view
    return "I'm doing terribly important things!"
  end
end

Instruction クラスに以下を追加しました。

def self.inherited(child)
    child.instance_eval do
      def model_name
        Instruction.model_name
      end
    end
    super
  end

%w(S_create_web_page).each {|r| require_dependency r } if Rails.env.development? 

=========

私のデータベース テーブルは、タイプ列にサブクラス名を適切に格納しているようで、サブクラスがロードされていることを確認しました。

(rdb) Module.const_get("SCreateWebPage")
SCreateWebPage(id: integer, name: string, code: string, skwerkflow_id: integer, created_at: datetime, updated_at: datetime, factory_id: integer, type: string)

===========

Instruction.rb の create メソッド内で get_view メソッドが呼び出されます。これらの特定の命令はそれぞれ独自のビューを持つことができると考えられています。get_view は、適切なビューを呼び出すためのメタプログラミングです。

問題: 明らかにインスタンス化され、サブクラスとして保存された命令で get_view を呼び出すと、サブクラス メソッドを呼び出すのではなく、基本クラスを呼び出します。

[30, 39] in /Users/alexedelstein/dev/skwerl/app/models/instruction.rb
   30    end
   31  
   32    #overridden by subclass to help controller find the right class-specific view.
   33    def get_view
   34      debugger
=> 35        return "I'm a pseudo abstract base method!"
   36      return nil
   37    end
   38  
   39    debugger
(rdb:13) self
#<Instruction id: 87, name: "Create Web Page", code: nil, skwerkflow_id: 38, created_at: "2013-07-18 01:00:40", updated_at: "2013-07-18 01:00:40", factory_id: nil, type: "SCreateWebPage">

==============

これは、何年も潜伏していた私の初めてのスタック オーバーフローへの投稿です。乾杯。

4

1 に答える 1

5

出力を見ると、 Instructionインスタンスでメソッドを呼び出しているように見えます。SCreateWebPageインスタンスはすべてInstructionインスタンスであるため、type 列の値に関係なく、Instructionインスタンスにすることができます。したがって、 SCreateWebPage.find(id)を実行していて、 Instruction.find( id)を実行していないことを再確認する必要があります。

型について心配したり、追加のクエリを実行したりしないようにするために、抽象メソッドで#becomesを使用することがあります。

class Instruction
  def get_view
    self.becomes(self.type.constantize).get_view
  end
end
于 2013-07-18T11:01:47.433 に答える