Associazioni has_many :through polimorfiche
Ho dovuto fare un’associazione has_many :through usando il polimorfsmo e mi sono accorto che l’associazione funzionava solo in un verso!! Allora cercando, anche con poca fatica, ho trovato questo articolo The other side of polymorphic :through associations nel quale viene spiegato il problema con le soluzioni.
Vi riporto il problema applicato al mio caso così c’è un esempio in più.
Ho una tabella newsletters una sentmails nella quale raccolgo l’id della newsletter e gli id “degli oggetti” (qui si applica il polimorfismo) a cui l’ho spedita:
1 2 3 create_table :newsletters do |t| 4 t.column :subject, :string 5 t.column :body, :text 6 t.column :html_body, :text 7 t.column :created_at, :datetime 8 t.column :updated_at, :datetime 9 end 10 11 create_table :sentmails do |t| 12 t.column :newsletter_id, :integer 13 t.column :subscriber_id, :integer 14 t.column :subscriber_type, :string 15 end 16 17 end 18 19 20 drop_table :newsletters 21 drop_table :sentmails 22 end 23 end
In sentmails ci sono i vari oggetti a cui posso spedire newsletter, per fare in modo che questi oggetti si comportino come subscribers ho fatto una libreria acts_as_asubscriber:
1 2 3 4 5 6 base.extend(ClassMethods) 7 end 8 9 10 11 write_inheritable_attribute(:acts_as_subscriber_options,{ 12 :subscriber_type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s, 13 :from => options[:from]}) 14 15 class_inheritable_reader :acts_as_subscriber_options 16 17 has_many :sentmails, :as => :subscriber 18 has_many :newsletters, :through => :sentmails 19 end 20 end 21 22 end 23 end 24 end 25 26 ActiveRecord::Base.class_eval do 27 include ActiveRecord::Acts::Subscriber 28 end
Poi dovrete fare altri due modelli Sentmail:
1 4 end
e Newsletter:
1 4 end 5
Così facendo se applicate acts_as_subscriber ad un modello User ad esempio potrete fare questo:
1 @newsletters = User.find(1).newsletters.find(:all)
e vedere tutte le newsletter inviate all’utente 1. Se però fate:
1 @users = Newsletter.find(1).users
vi darà errore!!
se però modificate il modello newsletter così:
1 8 end 9
allora vedrete che funziona e vi tirerà fuori tutti gli utenti a cui avete spedito la newsletter, il tutto a discapito delle prestazioni.


Kewl you should come up with that. Excllneet!