【问题标题】:Rails STI: Subclass methods not being called as expectedRails STI:未按预期调用子类方法
【发布时间】:2013-07-16 18:49:35
【问题描述】:

我有这个 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)

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

方法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">

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

这是我潜伏多年后第一次在 Stack Overflow 上发帖,所以请轻轻地把我花掉。干杯。

【问题讨论】:

  • 你是如何创建对象的?它可能只需要从数据库中重新加载。

标签: ruby-on-rails ruby activerecord sti


【解决方案1】:

通过查看输出,您似乎正在调用 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

【讨论】:

  • 使用“成为”就完美解决了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多