[Dbix-class] Bug with relationships on new objects.

brett gardner brett at clientcomm.com.au
Tue Jan 22 22:45:16 GMT 2008


Matt S Trout wrote:
> On Mon, Jan 21, 2008 at 01:04:21PM +0000, Scott Thomson wrote:
>   
>> On Jan 7, 2008 8:36 PM, Brett Gardner <brett at clientcomm.com.au> wrote:
>>     
>>> I'm not saying that the test is incorrect. That is when a foreign key is
>>> empty. The case that affects me is when the primary key is empty.
>>>
>>> To use the examples below, it is like saying that a new Artist owns all
>>> the existing CDs even though those CDs have their Artists set, until
>>> insert is called.
>>>
>>> Brett
>>>
>>>
>>> Brett Gardner wrote:
>>>       
>>>> I call new because I then call a method on the object which returns a
>>>> list of form controls to edit the object.
>>>>
>>>> In other cases I also have to set accessors before calling the insert
>>>> method.
>>>>
>>>> Jess Robinson wrote:
>>>>         
>>>>> On Mon, 7 Jan 2008, brett gardner wrote:
>>>>>
>>>>>           
>>>>>> The offending line is on line 793 of ResultSource.pm
>>>>>>
>>>>>> $ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
>>>>>>             
>>>>> That's because has_column_loaded returns true if the data is in/was
>>>>> loaded from the database, you're calling new(), which doesnt insert a
>>>>> new row into the database. So it's doing the correct thing.
>>>>>
>>>>> Call create() instead. That does new() and insert().
>>>>>
>>>>>           
>>>>>> my $undef_artist_cd = $schema->resultset("CD")->new_result({ 'title'
>>>>>> => 'badgers', 'year' => 2007 });
>>>>>> 207 is($undef_artist_cd->has_column_loaded('artist'), '', 'FK not
>>>>>> loaded');
>>>>>> 208 is($undef_artist_cd->search_related('artist')->count, 3, 'open
>>>>>> search on undef FK');
>>>>>>             
>>>>> new_result (or new) don't insert any data in the db, so this is
>>>>> perfectly correct.
>>>>>
>>>>>           
>>>>>> in 66relationship.t
>>>>>>
>>>>>> brett gardner wrote:
>>>>>>             
>>>>>>> I have a schema where there are clients who have subscribers.
>>>>>>>
>>>>>>> So there is an object "Client" which has a has_many relationship to
>>>>>>> "Subscriber".
>>>>>>>
>>>>>>> If I do the following
>>>>>>>
>>>>>>> my $client = $app->schema->resultset('Client')->find(...);
>>>>>>> my $subscribers = $client->subscribers;
>>>>>>>
>>>>>>> Then the relationship is correct and only pulls out the subscribers
>>>>>>> attached to that client.
>>>>>>>
>>>>>>> But if I do the following.
>>>>>>>
>>>>>>> my $client = $app->schema->resultset('Client')->new({});
>>>>>>> my $subscribers = $client->subscribers;
>>>>>>> Then all the subscribers are pulled out which is not ideal and
>>>>>>> potentially a very embarrassing privacy breach. Looking at the SQL
>>>>>>> generated by "$client->subscribers" it is not putting in the
>>>>>>> limiting where clause "WHERE me.client_id = ..."
>>>>>>>               
>>>>> As your row is not in the database, how would you expect it to do a
>>>>> where?
>>>>>
>>>>>
>>>>> Did you really miss all this, or am I misunderstanding your problem?
>>>>>
>>>>> Jess
>>>>>           
>
> << fixed top-posting and trimmed list footers, learn to use your
>    mail clients please people ... >>
>
>   
>> I've also run into a version of this problem. Mine occurs when
>> creating an object with an unset FK. It doesn't matter if the object
>> is new'd or created - it still doesn't have a key for the FK in
>> _column_data.
>>
>> I'm considering simply overriding 'new' where appropriate and
>> explicitly setting the FK(s) to undef but what concerns me is that the
>> behaviour of the created object is different from when the object is
>> loaded from the DB and I'm worried that this might bite me elsewhere.
>>     
>
> If the column value isn't present at all, maybe related_resultset should
> throw an exception on the grounds it can't actually create one yet?
>
> I can't see that breaking any code that isn't already terminally broken -
> does one of you guys want to have a go at writing a test case? (because
> that's how it'll get fixed :)
>
>   
Test case below

Index: 0.09/trunk/t/66relationship.t
===================================================================
--- 0.09/trunk/t/66relationship.t       (revision 3935)
+++ 0.09/trunk/t/66relationship.t       (working copy)
@@ -211,6 +211,10 @@
 is($def_artist_cd->has_column_loaded('artist'), 1, 'FK loaded');
 is($def_artist_cd->search_related('artist')->count, 0, 'closed search 
on null FK');
 
+my $undef_artist = $schema->resultset('Artist')->new_result({name=>'foo'});
+is($undef_artist->has_column_loaded('artist_id'),'','PK not set');
+is($undef_artist->search_related('cds')->count,0,'Open search on undef 
PK');
+
 # test undirected many-to-many relationship (e.g. "related artists")
 my $undir_maps = 
$schema->resultset("Artist")->find(1)->artist_undirected_maps;
 is($undir_maps->count, 1, 'found 1 undirected map for artist 1');




More information about the DBIx-Class mailing list