Ale*_*ein 2 ruby activerecord ruby-on-rails sti
我有这个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
Run Code Online (Sandbox Code Playgroud)
我在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?
Run Code Online (Sandbox Code Playgroud)
=========
我的数据库表似乎正在其类型列中正确存储子类名称,并且我已经验证了子类已加载:
(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)
Run Code Online (Sandbox Code Playgroud)
===========
方法get_view在Instruction.rb的create方法中调用.我们的想法是,每个特定指令都可以有自己的观点.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">
Run Code Online (Sandbox Code Playgroud)
==============
这是我在潜伏多年之后第一次发布Stack Overflow,所以请轻轻地给我打电话.干杯.
通过查看输出,看起来您正在调用一个指令实例上的方法.由于所有SCreateWebPage实例都是指令实例,因此无论类型列值如何,它们都可以是指令实例.所以你应该仔细检查你正在执行SCreateWebPage.find(id)而不是Instruction.find(id).
有时我在抽象方法中使用#becomes,以免担心类型而不执行其他查询:
class Instruction
def get_view
self.becomes(self.type.constantize).get_view
end
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
895 次 |
最近记录: |