使用belongs_to进行Rails对象继承

Rab*_*ott 5 inheritance ruby-on-rails single-table-inheritance

我在Report和Chart之间有一个简单的has_many/belongs_to关系.我遇到的问题是我的图表模型是有孩子的父母.

所以在我的报告模型中我有

class Report < ActiveRecord::Base
  has_many :charts
end
Run Code Online (Sandbox Code Playgroud)

我的图表模型是父模型,其中Pie,Line,Bar都继承自Chart.我不确定belongs_to:报告在图表模型中的位置,或图表模型的子项.我尝试访问chart.report时遇到错误,因为该对象的类型为"Class"

未定义的局部变量或方法`report'for#<Class:0x104974b90>

图表模型使用STI,因此它从图表表格中的chart_type列中拉出"性别"..我缺少什么?

编辑

      Chart
      /  \
    Pie  Line
    / \
   /   \
Gender Sex
Run Code Online (Sandbox Code Playgroud)

我(使用STI)实例化一个Gender或Sex类型的对象.希望这会有所帮助.

我有一种感觉,它的原因

@chart.update_attributes(params[:chart])
Run Code Online (Sandbox Code Playgroud)

因为当提交它的实际参数[:chart]其params [:gender]或params [:sex]

Mik*_*cic 2

您的问题是您有一个控制器接收所有这些不同类型的模型。当您使用 Rails 表单助手时,它们会从实例中获取对象类型并使用它来填充参数。这意味着你有params[:gender]而不是params[:chart]

您可以通过重写 Rails 用于生成表单的方法来解决此问题。将以下代码放入您的图表基类中:

def self.model_name
  name = "chart"
  name.instance_eval do
    def plural;   pluralize;   end
    def singular; singularize; end
  end
  return name
end
Run Code Online (Sandbox Code Playgroud)

现在,任何属于 Chart 子类的类都将被传递到您的接收操作中,如下所示params[:chart]

请记住,按照上面概述的方式更改对象名称可能会破坏某些依赖它的插件/gems 的功能。您应该考虑拥有多个控制器。不用 aChartsController来接收所有数据,而是使用 aGenderChartsController和 a LineChartsController。这有两个好处:

  1. 您不需要更改对象名称
  2. 如果您将来需要特定类型图表的自定义代码,则无需添加条件语句即可使其工作,因为不同的控制器已为您将其隔离。