使用belongs_to进行Rails对象继承

时间:2010-06-14 16:50:01

标签: ruby-on-rails inheritance single-table-inheritance

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

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

class Report < ActiveRecord::Base
  has_many :charts
end

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

  对于#&lt;

未定义的局部变量或方法`report'类:0x104974b90&GT;

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

修改

      Chart
      /  \
    Pie  Line
    / \
   /   \
Gender Sex

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

我感觉它是由

引起的
@chart.update_attributes(params[:chart])

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

4 个答案:

答案 0 :(得分:2)

你应该只能使用

class Report < ActiveRecord::Base
  has_many :charts
end

class Chart < ActiveRecord::Base
  belongs_to :report
end

并致电

@chart.report
@pie.report
@line.report
@bar.report

答案 1 :(得分: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

现在,作为图表子项的任何类都将作为params[:chart]

传递给您的接收操作

请注意,如上所述更改对象名称可能会破坏依赖它的某些插件/宝石的功能。你应该考虑拥有多个控制器。不是让ChartsController接收所有数据,而是GenderChartsControllerLineChartsController。这有两个好处:

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

答案 2 :(得分:1)

如果所有图表类型都属于报告,则放置

 belongs_to :report

在父模型中(​​我猜你的情况就是图表模型)。

答案 3 :(得分:0)

除非您明确覆盖chart_type,否则您的type列需要重命名为Base.inheritance_column

您是否明确将单表继承列重命名为chart_type