Jesse,<br><br>After the foobar commit r3908, I&#39;ve been digging deeper on the idea of relationships and I have not yet been able to come up with a consistent syntax for handling the more complex relationships I&#39;ve suggested here without breaking something. 
<br><br>If I assume that all refrences are based upon the ID column, it&#39;s no problem, but having the ability (which I&#39;m sure is nice) of creating references with alternative columns becomes problematic because you have to start worrying a lot more. Everything I think of is even more confusing.
<br><br>Thus, I&#39;m thinking of creating an index-relationship branch of JDBI that would add superior index (multiple columns) and relationship (indexes that link tables) handling to Jifty. This would be in addition to the &quot;references&quot; syntax for specifying relatively simple relationships. 
<br><br>However, I don&#39;t know what has been done on this or thought about this before. I was thinking that a Jifty::DBI::Index and Jifty::DBI::Relationship class with additional declarations &quot;index&quot; and &quot;relationsihp&quot; to go along side &quot;column&quot; would be nice, but I&#39;m not sure what you were considering on these fronts.
<br><br>Cheers,<br>Andrew<br><br><div><span class="gmail_quote">On 8/15/07, <b class="gmail_sendername">Andrew Sterling Hanenkamp</b> &lt;<a href="mailto:sterling@hanenkamp.com">sterling@hanenkamp.com</a>&gt; wrote:</span>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I spent much of today consider what can be done for relationships particularly after the discussion last month (&quot;Regarding refers_to and by on JDBI columns&quot;). I think I&#39;ve got a plan for a number of handy updates relating to relationships.
<br><br>I&#39;m already working on a patch to implement Idea 1. I think (at least the indirect record part) keeps things more consistent. The rest are sugar and I&#39;ll work to implement them too if everyone (particularly Jesse :) like B and III.
<br><br><span style="font-weight: bold;">Idea 1: Handling indirect relationships completely</span><br><br>Currently, Jifty handles two types of relationships that I call &quot;direct record&quot; and &quot;indirect collection&quot;. 
<br><br>Direct Record: You can uses the C&lt;references&gt; keyword to create a column in one model referring to a record in another model.<br><br>Indirect Collection: You can use the C&lt;references&gt; keyword with the C&lt;by&gt; keyword to create a virtual column that returns a collection of records such that the by column in the foreign records match the ID column of the current record.
<br><br>However, I think some effort will allow this to be expanded to handle two additional situations:<br><br>Indirect Record: This would allow the C&lt;references&gt; keyword with the C&lt;by&gt; keyword to create a virtual column that returns a single record such that by column in the foreign record matches the ID column of the current record. This would allow you to traverse a one-to-one relationship in both directions. For example,
<br><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; package App::Model::Employee;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp; use Jifty::DBI::Schema;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use App::Record schema {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column name =&gt; type is &#39;text&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column bio&nbsp; =&gt; references App::Model::Bio, is distinct;</span>

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; };</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp; package App::Model::Bio;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use Jifty::DBI::Schema;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp; use App::Record schema {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column employee =&gt; references App::Model::Employee by &#39;bio&#39;;</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column biography =&gt; type is &#39;text&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; };</span><br>

<br><br>Indirect Collection with Dereferencing: This adds a new keyword that would be used with C&lt;reference&gt; and C&lt;by&gt; called C&lt;dereference&gt;. Basically, the C&lt;dereference&gt; keyword would look up the the given column in the foreign model, which must be a reference to a record, and change the generated collection reference to return a collection for that record instead. This would allow you to have a many-to-many relationship with an invisible link table. For example,
<br><br><span style="font-family: courier new,monospace;">&nbsp; package App::Model::Employee;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use Jifty::DBI::Schema;</span>

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use App:Record schema {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column name =&gt; type is &#39;text&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column supervisors =&gt; references App::Model::ManagerCollection
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by &#39;supervisee&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dereference &#39;supervisor&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column supervisees =&gt; references App::Model::ManagerCollection
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by &#39;supervisor&#39;,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dereference &#39;supervisee&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; };</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; package App::Model::Manager;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp; use Jifty::DBI::Schema;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use App::Record schema {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column supervisor =&gt; references App::Model::Employee;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column supervisee =&gt; references App::Model::Employee;
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; };<br></span><br><span style="font-weight: bold;">Idea B: Adding reverse mutators to indirect relationships</span>

<br><br>The second step would be to add mutators to the indirect relationships allowing one to call backwards across a reverse relationship. <br><br>For collections, this would include an add_to_* and a delete_from_* methods for creating and deleting records related to a collection.
<br><br>For records, this would include a set_* which would perform the set operation on the passed record object (or load the record from the passed ID and then set).<br><br><span style="font-weight: bold;">Idea III: Adding the ability to create back-references in the originating file.
</span><br><br>Sometimes, it would be nice to be able to create the method calls to go from one direction to the other, but you don&#39;t have control over the foreign model. The specific possibility that could come up is in plugins, now that they can have their own models (blame me). It would be nice if the application could use tell Jifty to insert the back-reference methods in the other model.
<br><br>For example, here&#39;s a typical one-to-many relationship using the C&lt;backreference&gt; keyword as I imagine it:<br><br><span style="font-family: courier new,monospace;">&nbsp; package App::Model::Employee;</span>
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; use Jifty::DBI::Schema;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use App::Record schema {</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column name =&gt; type is &#39;text&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; };</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; package App::Model::Address;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp; use Jifty::DBI::Schema;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; use App::Record schema {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column employee =&gt; references App::Model::Employee,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; backreference &#39;addresses&#39;;
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column name =&gt; type is &#39;text&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column address =&gt; type is &#39;text&#39;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; };</span><br><br>With some help, similar logic could be applied to the indirect record and indirect collection with dereferencing examples above too.
<br><br>Cheers,<br><span class="sg">Andrew<br>
</span></blockquote></div><br>