Note that there are some explanatory texts on larger screens.

plurals
  1. PORetrieve model from polymorphic association via has_many through from STI model object
    primarykey
    data
    text
    <p>I want to use <strong>polymorphic association</strong> with a model which derives from a base class using <strong>single table inheritance (STI)</strong>. I already investigated further into this problem and (of course) dug through stackoverflow, e.g. here (<a href="https://stackoverflow.com/questions/1683265/activerecord-has-many-through-and-polymorphic-associations">ActiveRecord, has_many :through, and Polymorphic Associations</a>) and there (<a href="https://stackoverflow.com/questions/6582074/activerecord-has-many-through-polymorphic-associations-with-sti">ActiveRecord, has_many :through, Polymorphic Associations with STI</a>). Unfortunately all information I found regarded to polymorphic associations but not to the usage in the context of STI.</p> <p>In my current project I have a design which has one screenshot and many assets linked to it. Some assets (variation assets) should also have screenshots linked to them. Because a design has many assets I want to fetch all screenshots <em>through</em> them. </p> <p><strong>design.rb</strong></p> <pre><code>class Design &lt; ActiveRecord::Base has_one :screenshot, as: :screenshotable, dependent: :destroy has_many :assets, dependent: :destroy has_many :screenshots, through: :assets end </code></pre> <p><strong>screenshot.rb</strong></p> <pre><code>class Screenshot &lt; ActiveRecord::Base belongs_to :screenshotable, polymorphic: true end </code></pre> <p><strong>asset.rb</strong></p> <pre><code>class Asset &lt; ActiveRecord::Base belongs_to :design end </code></pre> <p><strong>variation_asset.rb</strong></p> <pre><code>class VariationAsset &lt; Asset # this is the important part as only a # variation asset should have a screenshot has_one :screenshot, as: :screenshotable, dependent: :destroy end </code></pre> <p>Assigning <code>Screenshot</code> to <code>VariationAsset</code> works well. Trying this with <code>Asset</code> raises an <code>NoMethodError</code> as expected (and wanted). Hence the polymorphic interface seems to work and was set up correctly in the schema.</p> <p><strong>schema.rb</strong></p> <pre><code>create_table "screenshots", :force =&gt; true do |t| t.string "name" t.integer "screenshotable_id" t.string "screenshotable_type" end create_table "assets", :force =&gt; true do |t| t.string "name" t.integer "design_id" t.string "type" end </code></pre> <p>Querying every <code>Screenshot</code> from a <code>Design</code> through the <code>Asset</code> raises the following error:</p> <p><strong>active_record/reflection.rb:509:in `check_validity!': Could not find the source association(s) :screenshot or :screenshots in model Asset. Try 'has_many :screenshots, :through => :assets, :source => '. Is it one of :design? (ActiveRecord::HasManyThroughSourceAssociationNotFoundError)</strong></p> <p>I tried it with the <code>:source</code> parameter as suggested in the error message but this also did not help.</p> <p>It works when I put the <code>has_one :screenshot, as: :screenshotable, dependent: :destroy</code> line into the STI base class <code>Asset</code>:</p> <pre><code>class Asset &lt; ActiveRecord::Base belongs_to :design has_one :screenshot, as: :screenshotable, dependent: :destroy end </code></pre> <p>I think it has something to do with the <code>through:</code> parameter and the fact that it seems (for me) to be impossible to tell it to look into <code>VariationAsset</code> instead of <code>Asset</code> somehow.</p> <p>You find a "working" example of the above code at my <a href="https://github.com/Partyschaum/active_record_playground/tree/polymorphic_sti" rel="nofollow noreferrer">github repo</a>.</p> <p>Any help appreciated! :-)</p>
    singulars
    1. This table or related slice is empty.
    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