Getting note only the class instances but also instances of subclasses on a has_many associations

Hello,
I have a model like this:
## Model
class ContainerCharge < ShipmentCharge
  belongs_to :container
end

class Container < ActiveRecord::Base
  has_many :container_charges
end

class HandlingContainerCharge < ContainerCharge
end
class ShippingContainerCharge < ContainerCharge
end

## Controller

#Please assume here that this container has many Handling and Shipping
charges
container.container_charges # <- doesn't return the handling and
shipping charges, only instances of the the super class
ContainerCharge

I would like the association to return all the container charges which
should be the right thing to do....
Anyone knows how to do this?

Regards,
Gam.

I would like the association to return all the container charges which
should be the right thing to do....
Anyone knows how to do this?

Does this only happen if cache_classes is set to false ?

Fred

Fred,

I don't think that's the issue here. It seems to me that the problem
is the two-level STI

ShippingCharge
   ContainerCharge
       HandlingContainerCharge
       ShippingContainerCharge

So, since ContainerCharge is an STI subclass, the association

has_many :container_charges

is going to add a where clause restricting the results to those where
the type is "ContainerCharge".

I haven't tested it but perhaps

has_many :container_charges,
                :class_name => 'ShippingCharge',
                :conditions => {:type => %w(ContainerCharge
HandlingContainerCharge ShippingContainerCharge)}

Hi Fred,
nope, with cache_classes = true it behaves the same way...

I don't think that's the issue here. It seems to me that the problem
is the two-level STI

ShippingCharge
ContainerCharge
HandlingContainerCharge
ShippingContainerCharge

So, since ContainerCharge is an STI subclass, the association

has_many :container_charges

is going to add a where clause restricting the results to those where
the type is "ContainerCharge".

STI is a bit funny in development mode - if the class isn't loaded,
rails doesn't know that it exists and so doesn't know to include that
particular type in the where condition on type. I've got STI mixed
with associations in a few places and (as long as it knows that the
subclasses exist) a has_many like that does pull in subclasses. I
normally end up using require_dependency on the subclasses at the
bottom of the file defining the parent class

Fred

Hi Rick,
Of course I should have looked at the SQL query... and indeed, you are
perfectly right, Rails adds a WHERE clause on type... and it has to to
filter out the classes that are NOT involved:
SELECT count(*) AS count_all FROM "charges" WHERE
("charges".container_id = 1) AND ( ("charges"."type" =
'ContainerCharge' ) )

Your idea is almost there, but Rails insists with the last AND clause
on the type.... any idea on how to get ride of it?:
SELECT count(*) AS count_all FROM "charges" WHERE
("charges".container_id = 1 AND ("charges"."type" IN
('ContainerCharge','HandlingContainerCharge','ShippingContainerCharge')))
AND ( ("charges"."type" = 'ContainerCharge' ) )

Thanks guys for your time. REALLY appreciated!
Regards,
Gam.

PS: I just realized that I didn't specify that I'm using a STI... but
you figured it out...

Hi Rick,
Of course I should have looked at the SQL query... and indeed, you are
perfectly right, Rails adds a WHERE clause on type... and it has to to
filter out the classes that are NOT involved:
SELECT count(*) AS count_all FROM "charges" WHERE
("charges".container_id = 1) AND ( ("charges"."type" =
'ContainerCharge' ) )

It should just be a case of ensuring all the subclasses of
container_charge are loaded

Fred

I have added:
  has_many :container_charges,
     :class_name => 'Charge',
     :conditions => {:type => %w(ContainerCharge
HandlingContainerCharge ShippingContainerCharge)}

With this, Rails remove the problematic ##AND ( ("charges"."type" = >
'ContainerCharge' ) ) ##. This seems like a big workaround not so
pretty but it works in the console. Now the field_for method doesn't
see the charges in a form_for and I don't know why... I'm almost
there!

Now the field_for method doesn't
see the charges in a form_for and I don't know why... I'm almost
there!

Silly me, forgot the: accepts_nested_attributes_for :container_charges

Well, it's hacky but it works. I'll report here if I run into other
troubles because of this trick.

Regards,
Gam.

I ran into problem when I wanted to mass assign via the association.
The class of the new object will be of the topclass.
The solution is here:
http://stackoverflow.com/questions/1601739/rails-attr-accessible-does-not-work-for-type

and in your form, use :type_helper