Stephen Bannasch
2007-May-23 02:57 UTC
combining has_many :through and polymorphic associations
I''m trying to combine has_many :through and polymorphic associations. I''ve got it working one way but the other way it fails. Here''s the domain I''m trying to model: I''ve got a number of different authorable objects including Activities and Simulations. Each authorable object can be related to 0 or more Subjects such as Math, Science, etc. I''d like to be able ask the following types of questions: 1) list all activities that have the subject Math 2) list all authorable objects hat have the subject Science 3) list all the subjects for an Activity 4) list all the subjects for a Simulation I used this as a reference: http://dev.rubyonrails.org/ticket/7143: [PATCH] allow polymorphic :source for has_many :through I''ve tried this on edge Rails (rev 6786) and v1.2.3. Here are my ActiveRecord models: class Activity < ActiveRecord::Base has_many :subjectings has_many :activity_subjects, :through => :subjectings, :source => :subjectable, :source_type => ''Activity'' end class Simulation < ActiveRecord::Base has_many :subjectings has_many :activity_subjects, :through => :subjectings, :source => :subjectable, :source_type => ''Simulation'' end class Subject < ActiveRecord::Base has_many :subjectings has_many :subject_activities, :through => :subjectings, :source => :subjectable, :source_type => ''Activity'' has_many :subject_simulations, :through => :subjectings, :source => :subjectable, :source_type => ''Simulation'' end class Subjecting < ActiveRecord::Base belongs_to :subject belongs_to :subjectable, :polymorphic => true end This works well from the Subject side of things but there is something wrong from the Activity or Simulation side of the association. Here''s my schema: create_table "activities", :force => true do |t| t.column "name", :string end create_table "simulations", :force => true do |t| t.column "name", :string end create_table "subjectings", :force => true do |t| t.column "subject_id", :integer t.column "subjectable_id", :integer t.column "subjectable_type", :string end create_table "subjects", :force => true do |t| t.column "name", :string end Here''s the testing in script/console:>> activity_fractions = Activity.create(:name => "Fractions") >> activity_decimals = Activity.create(:name => "Decimals") >> activity_density = Activity.create(:name => "Density") >> activity_batteries = Activity.create(:name => "Batteries") >> simulation_ratios = Simulation.create(:name => "Interactive Ratios") >> simulation_base10 = Simulation.create(:name => "Powers of Ten") >> simulation_buoyancy = Simulation.create(:name => "Buoyancy Game") >> simulation_circuits = Simulation.create(:name => "Circuit Kit") >> math = Subject.create(:name => "Math") >> science = Subject.create(:name => "Science") >> math.subject_activities.push(activity_fractions, activity_decimals) >> math.subject_simulations.push(simulation_ratios, simulation_base10) >> science.subject_activities.push(activity_density, activity_batteries) >> science.subject_simulations.push(simulation_buoyancy, simulation_circuits)I can get the activities that have the subject "Math":>> math.subject_activities.each { |a| puts "#{a.id}: #{a.name}" }; nil1: Fractions 2: Decimals I can also get the simulations that have the subject "Math":>> math.subject_simulations.each { |s| puts "#{s.id}: #{s.name}" }; nil1: Interactive Ratios 2: Powers of Ten Or I can get all the authorable objects that have the subject "Math":>> math.subjectings.each { |s| puts "#{s.subjectable.id}: >>#{s.subjectable_type}, name: #{s.subjectable.name}, class: >>#{s.subjectable.class}" }; nil1: Activity, name: Fractions, class: Activity 2: Activity, name: Decimals, class: Activity 1: Simulation, name: Interactive Ratios, class: Simulation 2: Simulation, name: Powers of Ten, class: Simulation But trying to get the subjects for an activity fails:>> activity_fractions.activity_subjectsActiveRecord::StatementInvalid: Mysql::Error: #42S22Unknown column ''subjectings.activity_id'' in ''where clause'': SELECT activities.* FROM activities INNER JOIN subjectings ON activities.id = subjectings.subjectable_id AND subjectings.subjectable_type = ''Activity'' WHERE ((subjectings.activity_id = 1)) Thanks for any pointers. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---