reset association cache for polymorphism

Hi,

I have a product class with category and a polymorphic attributes details_info, that depending on category go to one or another table to get the detail

Class Product

category

details_info

end

Class DetailsInfo

end

Class Pencil

include DetailsInfo

type

color

end

Class Notebook

include DetailsInfo
size

end

and to display products i do

prds = Products.all

prds.each do |pr|

if pr.category == ‘pencil’

DetailsInfo.table_name = ‘pencil’

else if pr.category == ‘notebook’

DetailsInfo.table_name = ‘notebook’

end

end

(this is just kind of algo I use)

All this was working fine but with rails > 4.2 , it doesnt work anymore.

The first time pr.details_info will be called, it seems that the table name is cached somewhere, and then all other products are using the same table_name. When I check during loop, I can see that DetailsInfo.table_name is always correct, but still when pr.details_info will be called , it used the first table_name that was used. I can also see that the method table_name is called every step of the loop, and it return the good table_name, but still, the sql request search on bad table.

How can I reset that ? Ive tried a lot a thing like emptying association_cache, also different things with reflect_on_all_associations, reset_column_information, reload, …

thanks

As mentioned on rails-core, I’d recommend looking into polymorphic associations for this. Here’s a possible example:


class Product < ActiveRecord::Base

# the products table has two columns relevant here:

#   * details_info_id, integer

#   * details_info_type, string

belongs_to :details_info, polymorphic: true

end

class Pencil < ActiveRecord::Base

has_many :products, as: :details_info

end

class Notebook < ActiveRecord::Base

has_many :products, as: :details_info

end

Given those models, if you retrieve a list of Product objects you should be able to access each one’s details_info from the correct tables.

If you’re still unsure how to proceed, more detail on the specifics of your schema and desired functionality would be useful.

–Matt Jones

Thanks a lot for answer, Unfortunately, it is an site existing for several years, so I cant change model, so I really need to be able to change “manually” the table_name or to make like a patch forcing to check if table_name has been changed and then update association cache

Call self.table_name = :table on each model

thanks for answer. But Im not sure tu understand
where or when shall I call this ?

cause im already doing

DetailsInfo.table_name = ‘pencil’

Do it inside the class

so I tried this

Class Pencil

self.table_name = :table

include DetailsInfo

type

color

end

Class Notebook

self.table_name = :table
include DetailsInfo
size

end

but still same problem. Do I get it wrong ?

replace :table with the right table name?

it doesnt work either, still same problem