5

I have a simple has_many/belongs_to relationship between Report and Chart. The issue I'm having is that my Chart model is a parent that has children.

So in my Report model I have

class Report < ActiveRecord::Base
  has_many :charts
end

And my Chart model is a parent, where Pie, Line, Bar all inherit from Chart. I'm not sure where the belongs_to :report belongs within the chart model, or children of chart model. I get errors when I attempt to access chart.report because the object is of type "Class"

undefined local variable or method `report' for #< Class:0x104974b90>

The Chart model uses STI so its pulling say.. 'Gender' from the chart_type column in the charts table.. what am I missing?

EDIT

      Chart
      /  \
    Pie  Line
    / \
   /   \
Gender Sex

I am (using STI) instantiating an object of type Gender, or Sex. Hopefully this helps a bit more.

I have a feeling that its caused by

@chart.update_attributes(params[:chart])

because when submitted its actually params[:chart] its params[:gender] or params[:sex]

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
Rabbott
  • 4,282
  • 1
  • 30
  • 53
  • 1. Does your Chart table have a 'type' column? 2. Do your Pie and Line classes inherit from Chart? (`Pie < Chart`) 3. What are you trying to illustrate about Gender and Sex in your tree? Are they also classes? Or attributes of the Pie model? – John Bachir Jun 24 '10 at 23:27
  • 1. Yes, chart_type, which I handle with a getter in the model. 2. Yes, Pie inherits from Chart. 3. Gender and Sex are model, since they have their own calculations they would run on the data. Each model, or chart type, has a method to calculate values, then calls super to display since they all display the same type of chart (Pie) – Rabbott Jun 25 '10 at 05:16

4 Answers4

2

You should be able to use just

class Report < ActiveRecord::Base
  has_many :charts
end

class Chart < ActiveRecord::Base
  belongs_to :report
end

and call

@chart.report
@pie.report
@line.report
@bar.report
Ju Nogueira
  • 8,435
  • 2
  • 29
  • 33
2

Your problem is that you have one controller receiving all these different types of models. When you use the Rails form helpers, they're taking the object type from the instance and using that to populate the params. This means that you have params[:gender] instead of params[:chart]

You can fix this by overriding the method that Rails uses to generate the form. Put the following code in your base chart class:

def self.model_name
  name = "chart"
  name.instance_eval do
    def plural;   pluralize;   end
    def singular; singularize; end
  end
  return name
end

Now, any class that is a child of Chart will be passed into your receiving action as params[:chart]

Keep in mind that changing the object name as I've outlined above could break functionality of some plugins/gems that rely on it. You should look into having multiple controllers. Instead of having a ChartsController to receive all of the data, have a GenderChartsController and a LineChartsController. This provides two benefits:

  1. You don't need to change the object name
  2. If you need custom code for a specific type of chart in the future, you don't have to add conditional statements to make it work, as the different controllers have segregated it for you.
Mike Trpcic
  • 25,305
  • 8
  • 78
  • 114
1

If all the chart types belong to a report, then place

 belongs_to :report

in the parent model ( that is Chart Model in your case I am guessing).

Rishav Rastogi
  • 15,484
  • 3
  • 42
  • 47
0

Your chart_type column needs to be renamed to just type, unless you explicitly overwrote Base.inheritance_column.

Did you explicitly rename the single table inheritance column to chart_type?

nfm
  • 19,689
  • 15
  • 60
  • 90