<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Plain Text Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.5pt;
        font-family:Consolas;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.PlainTextChar
        {mso-style-name:"Plain Text Char";
        mso-style-priority:99;
        mso-style-link:"Plain Text";
        font-family:Consolas;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body lang=EN-US link=blue vlink=purple>

<div class=Section1>

<p class=MsoPlainText>Hi there,<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>We're currently upgrading our DBIC from v0.08012 to the
latest version (v0.08120) on a project I'm working on.&nbsp; Most things are going
smoothly, but we've run into a use case for find_or_create_related that used to
work in the older DBIC but no longer does.&nbsp; We had some code that was calling
$row-&gt;find_or_create_related('rel', { ... }) on a new row object that hasn't
been inserted into the database yet.&nbsp; This ought to work because the
relationship is a belongs_to, so it doesn't need to know anything about $row.&nbsp;
In the new version, the related row is always created regardless of whether the
related object already exists in the DB.<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>We can change the code easily to just call
find_or_create() on the related table itself, but we were doing it this way
because we wanted to find_or_create on the related table without having to know
what class to search on (that's my guess, anyway - the original impetus for the
way this was written is long gone now).&nbsp; Having the new row object and the
relationship names was an easy way to do this, and seems like a quirky yet
valid use case, so I would argue that it ought to be supported.&nbsp; Or at least it
would be nice if there was some kind of error or warning or something, rather
than the current behavior which is to silently create a new row in the related
table even if the find() would have succeeded.<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>I'll provide more detail about my exact use case below,
and I'm happy to provide anything else.<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>We have two related tables, build_data and build_urls,
which are pasted below with the irrelevant columns and relationships removed:<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=======================<o:p></o:p></p>

<p class=MsoPlainText>=== BEGIN BuildData ===<o:p></o:p></p>

<p class=MsoPlainText>=======================<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>package NBT::Schema::Icebox::BuildData;<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText># Created by DBIx::Class::Schema::Loader # DO NOT MODIFY
THE FIRST PART OF THIS FILE<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>use strict;<o:p></o:p></p>

<p class=MsoPlainText>use warnings;<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>use base 'DBIx::Class::Core';<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head1 NAME<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>NBT::Schema::Icebox::BuildData<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=cut<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;table(&quot;build_data&quot;);<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head1 ACCESSORS<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head2 id<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>&nbsp; data_type: INT<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; default_value: undef<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; extra: HASH(0xa042260)<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_auto_increment: 1<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_nullable: 0<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; size: 10<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head2 build_url<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>&nbsp; data_type: INT<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; default_value: undef<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; extra: HASH(0xa047638)<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_foreign_key: 1<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_nullable: 1<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; size: 10<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=cut<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;add_columns(<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;id&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; {<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; data_type =&gt; &quot;INT&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; default_value =&gt; undef,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; extra =&gt; { unsigned =&gt; 1 },<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_auto_increment =&gt; 1,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_nullable =&gt; 0,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; size =&gt; 10,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; },<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;build_url&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; {<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; data_type =&gt; &quot;INT&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; default_value =&gt; undef,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; extra =&gt; { unsigned =&gt; 1 },<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_foreign_key =&gt; 1,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_nullable =&gt; 1,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; size =&gt; 10,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; },<o:p></o:p></p>

<p class=MsoPlainText>);<o:p></o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;set_primary_key(&quot;id&quot;);<o:p></o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;add_unique_constraint(&quot;build_pxe_branch&quot;,
[&quot;build_url&quot;, &quot;pxe_kernel&quot;, &quot;branch&quot;]);<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head1 RELATIONS<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head2 build_url<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>Type: belongs_to<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>Related object: L&lt;NBT::Schema::Icebox::BuildUrls&gt;<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=cut<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;belongs_to(<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;build_url&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;NBT::Schema::Icebox::BuildUrls&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; { id =&gt; &quot;build_url&quot; },<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; { join_type =&gt; &quot;LEFT&quot; },<o:p></o:p></p>

<p class=MsoPlainText>);<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=======================<o:p></o:p></p>

<p class=MsoPlainText>=== BEGIN BuildUrls ===<o:p></o:p></p>

<p class=MsoPlainText>=======================<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>package NBT::Schema::Icebox::BuildUrls;<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText># Created by DBIx::Class::Schema::Loader # DO NOT MODIFY
THE FIRST PART OF THIS FILE<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>use strict;<o:p></o:p></p>

<p class=MsoPlainText>use warnings;<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>use base 'DBIx::Class::Core';<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head1 NAME<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>NBT::Schema::Icebox::BuildUrls<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=cut<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;table(&quot;build_urls&quot;);<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head1 ACCESSORS<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head2 id<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>&nbsp; data_type: INT<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; default_value: undef<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; extra: HASH(0xa04789c)<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_auto_increment: 1<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_nullable: 0<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; size: 10<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head2 name<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>&nbsp; data_type: VARCHAR<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; default_value: undef<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; is_nullable: 0<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; size: 255<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=cut<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;add_columns(<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;id&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; {<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; data_type =&gt; &quot;INT&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; default_value =&gt; undef,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; extra =&gt; { unsigned =&gt; 1 },<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_auto_increment =&gt; 1,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_nullable =&gt; 0,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; size =&gt; 10,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; },<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;name&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; {<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; data_type =&gt; &quot;VARCHAR&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; default_value =&gt; undef,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; is_nullable =&gt; 0,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; size =&gt; 255,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; },<o:p></o:p></p>

<p class=MsoPlainText>);<o:p></o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;set_primary_key(&quot;id&quot;);<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head1 RELATIONS<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=head2 build_datas<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>Type: has_many<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>Related object: L&lt;NBT::Schema::Icebox::BuildData&gt;<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>=cut<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>__PACKAGE__-&gt;has_many(<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;build_datas&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; &quot;NBT::Schema::Icebox::BuildData&quot;,<o:p></o:p></p>

<p class=MsoPlainText>&nbsp; { &quot;foreign.build_url&quot; =&gt;
&quot;self.id&quot; },<o:p></o:p></p>

<p class=MsoPlainText>);<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText># Created by DBIx::Class::Schema::Loader v0.05003 @
2010-03-17 16:38:08 # DO NOT MODIFY THIS OR ANYTHING ABOVE!
md5sum:Ln4fU7T0Koi6pqWzS6APfw<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>===================<o:p></o:p></p>

<p class=MsoPlainText>=== END PASTIES ===<o:p></o:p></p>

<p class=MsoPlainText>===================<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>We have some code that does a find_or_create_related call
like this:<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; $build_datum =
$schema-&gt;resultset(&quot;NBT::Schema::Icebox::BuildData&quot;)-&gt;new_result({});<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; # actually we loop through a list of relationships
next, but I'm keeping it simple for the sake of the example<o:p></o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp;
$build_datum-&gt;find_or_create_related(&quot;build_url&quot;, { name =&gt;
'...' });<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>This produces some strange SQL that looks like this:<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>&nbsp;&nbsp;&nbsp; SELECT me.id, me.name, me.modified_ts FROM build_urls
me WHERE ( ( me.name = ? AND 1 = 0 ) ): '...'<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>The 'AND 1 = 0' condition makes the select impossible, so
a related row is always created.&nbsp; The impossible condition seems to come from
DBIx::Class::ResultSource-&gt;_resolve_condition(), which decides that the
relationship condition is unresolvable and returns \'1 = 0'.&nbsp; The condition is
'unresolvable' because the build_url column is not in_storage on $build_datum,
because $build_datum is a new_result.&nbsp; If the 'AND 1 = 0' were left out, this
would do the right thing, I think.&nbsp; But maybe theres a good reason for its
existence in this case and I'm just confused?<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>Thanks for your time,<o:p></o:p></p>

<p class=MsoPlainText><o:p>&nbsp;</o:p></p>

<p class=MsoPlainText>Byron Young (original author, I&#8217;m sending this for
him since he can&#8217;t mail the list for some reason -Robert)<o:p></o:p></p>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

</body>

</html>