The app I'm developing has 3 main models and many single table inheritance models:
- Question
- User
- Professional
- Representant
- Taxonomy
- Category
- Topic
- Profession
- Locality
- Region
- Country
There are multiple kinds of users (User
, Professional < User
, Representant < User
) which all inherit from the User class with single table inheritance.
There are multiple kinds of taxonomies (Category < Taxonomy
, Topic < Taxonomy
, Profession < Taxonomy
, Locality < Taxonomy
, Region < Taxonomy
, Country < Taxonomy
) which all inherit from the Taxonomy class with single table inheritance.
Questions, as well as professionals are also under taxonomies via many to many relationships (they can have many topics, many professions, many categories, etc...)
Now, I'm looking for a way to establish that many to many relationship between those polymorphic objects. I've tried the has_many :through
solution and created a Classification class.
Migration file:
class CreateClassifications < ActiveRecord::Migration
def change
create_table :classifications, :id => false do |t|
t.references :classifiable, :null => false, :default => 0, :polymorphic => true
t.references :taxonomy, :null => false, :default => 0, :polymorphic => true
end
add_index :classifications, [:classifiable_id, :taxonomy_id]
add_index :classifications, [:taxonomy_id, :classifiable_id]
end
end
Model file:
class Classification < ActiveRecord::Base
attr_accessible :classifiable, :classifiable_id, :classifiable_type,
:taxonomy, :taxonomy_id, :taxonomy_type
belongs_to :classifiable, :polymorphic => true
belongs_to :taxonomy, :polymorphic => true
end
I've then added has_many :through
associations for Questions, Professionals, and Taxonomies.
Taxonomy.rb
has_many :classifications, :as => :taxonomy, :foreign_key => :taxonomy_id
has_many :classifiables, :through => :classifications, :source => :classifiable
has_many :users, :through => :classifications, :source => :classifiable, :source_type => "User"
has_many :professionals, :through => :classifications, :source => :classifiable, :source_type => "Professional"
has_many :representants, :through => :classifications, :source => :classifiable, :source_type => "Representant"
has_many :questions, :through => :classifications, :source => :classifiable, :source_type => "Question"
has_many :guides, :through => :classifications, :source => :classifiable, :source_type => "Guide"
Question.rb
has_many :classifications, :as => :classifiable, :foreign_key => :classifiable_id, :dependent => :destroy
has_many :taxonomies, :through => :classifications, :source => :taxonomy
has_many :topics, :through => :classifications, :source => :taxonomy, :source_type => "Topic"
Professional.rb
has_many :classifications, :as => :classifiable, :foreign_key => :classifiable_id, :dependent => :destroy
has_many :taxonomies, :through => :classifications, :source => :taxonomy
has_many :topics, :through => :classifications, :source => :taxonomy, :source_type => "Topic"
has_many :professions, :through => :classifications, :source => :taxonomy, :source_type => "Profession"
Now, after setting up all this, things do not work very well...
I can't seem to assign taxonomies to Professionals or Questions (i.e.
Question.create(:title => "Lorem Ipsum Dolor Sit Amet", :author => current_user, :topics => [list of topics,...])
works well except for topics which are not saved.)Where clauses don't work as they should (i.e.
Question.joins(:topics).where(:conditions => {:topics => {:id => [list of topics,...]}})
fails with ano such column: "Topics"."id"
error.
Any help? Thanks!
UPDATE
I have installed the gem 'store_base_sti_class' as indicated. It had the desired effect on the Classification model.
#<Classification classifiable_id: 1, classifiable_type: "Professional", taxonomy_id: 17, taxonomy_type: "Topic">
However, when I query topics (Professional.find(1).topics
), ActiveRecord is still looking for the class "User" instead of "Professional"...
SELECT "taxonomies".* FROM "taxonomies" INNER JOIN "classifications" ON "taxonomies"."id" = "classifications"."taxonomy_id" WHERE "taxonomies"."type" IN ('Topic') AND "classifications"."classifiable_id" = 1 AND "classifications"."classifiable_type" = 'User' AND "classifications"."taxonomy_type" = 'Topic'
Any idea how to fix it for both?