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:

and in your form, use :type_helper