Note that there are some explanatory texts on larger screens.

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

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload