Laravel dynamic relationships - access model attributes on eager load
<p>I have an Eloquent relationship on my Laravel model which is dynamic - that is, the value of a particular database field determines which model will get loaded. I am able to load this relationship fine when I first instantiate the model instance and then reference the relation, but it does not work when I eager load that relationship.</p>

<p>Specifically, I have a <code>Product</code> model. That product might or might not be a parent to another product. If the <code>parent_id</code> of the Product is set to <code>0</code> then that product is considered a parent part (whether or not it has children). If the <code>parent_id</code> is set to a different product's id, then that product is a child. I need to be able to access <code>Product::with('parent')</code> and know that the <code>parent</code> relation will return with <em>either</em> itself (yes, duplicated data) or a different product if it is a child.</p>

<p>Here is my relationship so far:</p>

<pre><code>public function parent()
{
    if ($this-&gt;parent_id &gt; 0) {
        return $this-&gt;belongsTo('App\Product', 'parent_id', 'id');
    } else {
        return $this-&gt;belongsTo('App\Product', 'id', 'id');
    }
}
</code></pre>

<p>When I am eager loading, <code>$this-&gt;parent_id</code> is always undefined and therefore this relation will only ever return itself even if it actually is a parent product.</p>

<p>Is there any way to access a model's attributes <em>before</em> a relation is eager loaded? I thought about working in a separate query before I return the relation, but I realized that I don't have access to the product's id to even run that query.</p>

<p>If that is not possible, what are some other ways to address this type of problem? It does not appear that this could be solved through a traditional polymorphic relationship. I only have two possible ideas:</p>

<ul>
<li>Add some sort of constraint to the <code>belongsTo</code> relation where I dynamically determine a foreign key.</li>
<li>Create my own custom relationship that uses a foreign key based on a different database field.</li>
</ul>

<p>I honestly have no idea how I would implement either of those. Am I going about this the right way? Is there something I am overlooking?</p>

<hr>

<p>After thinking this over more, I think the simplest way to put the question is: <strong>is there any way to dynamically select a foreign key for a relationship inside the relation itself at runtime</strong>? My use cases don't allow for me to use eager loading constraints when I call the relation - the constraints need to apply to the relation itself.</p>