From 1120eafb56694be4c270547c5587a56c5a129a90 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Mon, 23 Dec 2013 15:43:27 +0100 Subject: [PATCH 1/5] better explanation for optional fk values in rels --- lib/DBIx/Class/Relationship.pm | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/DBIx/Class/Relationship.pm b/lib/DBIx/Class/Relationship.pm index 26a07ef0e..809834209 100644 --- a/lib/DBIx/Class/Relationship.pm +++ b/lib/DBIx/Class/Relationship.pm @@ -192,14 +192,14 @@ more info see L. $book->get_column('author_id'); -If the relationship is optional -- i.e. the column containing the -foreign key can be NULL -- then the belongs_to relationship does the +If the the column containin the foreign key of a relationship +can be NULL the belongs_to relationship still does the right thing. Thus, in the example above C<< $obj->author >> would -return C. However in this case you would probably want to set -the L attribute so that -a C is done, which makes complex resultsets involving -C or C operations work correctly. The modified -declaration is shown below: +return C. However you probably want to set the +L attribute so that +a C is done, which makes relationship traversal in complex +resultsets work correctly. (i.e. resultsets involving C or +C operations). The modified declaration is shown below: # in a Book class (where Author has_many Books) __PACKAGE__->belongs_to( @@ -209,7 +209,6 @@ declaration is shown below: { join_type => 'left' } ); - Cascading deletes are off by default on a C relationship. To turn them on, pass C<< cascade_delete => 1 >> in the $attr hashref. From 21b5fecd86b603109f1e8ab565267efb75012846 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Mon, 30 Dec 2013 09:46:40 +0100 Subject: [PATCH 2/5] better explanation for optional fk values in rels (2nd try) --- lib/DBIx/Class/Relationship.pm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/DBIx/Class/Relationship.pm b/lib/DBIx/Class/Relationship.pm index 809834209..979630fea 100644 --- a/lib/DBIx/Class/Relationship.pm +++ b/lib/DBIx/Class/Relationship.pm @@ -191,14 +191,13 @@ more info see L. # To retrieve the plain id if you used the ugly version: $book->get_column('author_id'); - -If the the column containin the foreign key of a relationship -can be NULL the belongs_to relationship still does the -right thing. Thus, in the example above C<< $obj->author >> would -return C. However you probably want to set the +If the column containing the foreign key of a relationship +is nullable, the belongs_to relationship still does the +right thing. (i.e. C<< $obj->author >> would return C). +However you probably want to set the L attribute so that -a C is done, which makes relationship traversal in complex -resultsets work correctly. (i.e. resultsets involving C or +a C is done. This ensures that relationship traversal works +consistently in all situations. (i.e. resultsets involving C or C operations). The modified declaration is shown below: # in a Book class (where Author has_many Books) From 26e03138c214ca4a7bfe3bec76b6e33197c89419 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Mon, 30 Dec 2013 09:52:48 +0100 Subject: [PATCH 3/5] better explanation for optional fk values in rels (3rd try) --- lib/DBIx/Class/Relationship.pm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/DBIx/Class/Relationship.pm b/lib/DBIx/Class/Relationship.pm index 979630fea..634b96611 100644 --- a/lib/DBIx/Class/Relationship.pm +++ b/lib/DBIx/Class/Relationship.pm @@ -191,11 +191,8 @@ more info see L. # To retrieve the plain id if you used the ugly version: $book->get_column('author_id'); -If the column containing the foreign key of a relationship -is nullable, the belongs_to relationship still does the -right thing. (i.e. C<< $obj->author >> would return C). -However you probably want to set the -L attribute so that +If the foreign key column is nullable you probably want to set +the L attribute so that a C is done. This ensures that relationship traversal works consistently in all situations. (i.e. resultsets involving C or C operations). The modified declaration is shown below: From 3384a22755789676e667722cc0fcdd99f88f8af1 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Mon, 30 Dec 2013 10:32:32 +0100 Subject: [PATCH 4/5] fixed typo --- lib/DBIx/Class/Manual/Cookbook.pod | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 36b891e11..0cb560bdf 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -1183,7 +1183,7 @@ of your application to support a change lifecycle (e.g. DEV, TEST, PROD) and the DB schemas are named based on the environment (e.g. database1_dev). However, one can dynamically "map" to the proper DB schema by overriding the -L method in your Schema class and +L method in your Schema class and building a renaming facility, like so: package MyApp::Schema; @@ -1223,13 +1223,13 @@ building a renaming facility, like so: 1; -By overriding the L +By overriding the L method and extracting a custom option from the provided \%attr hashref one can then simply iterate over all the Schema's ResultSources, renaming them as needed. To use this facility, simply add or modify the \%attr hashref that is passed to -L, as follows: +L, as follows: my $schema = MyApp::Schema->connect( From 5911039bd718a582544300c2900f93affb378c43 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Mon, 30 Dec 2013 10:32:53 +0100 Subject: [PATCH 5/5] recipe for rels with optional fk values --- lib/DBIx/Class/Manual/Cookbook.pod | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 0cb560bdf..1c60acf76 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -1244,6 +1244,39 @@ L, as follows: Obviously, one could accomplish even more advanced mapping via a hash map or a callback routine. +=head2 Relationships with optional foreign key values + +Sometimes you want a relationship where the column holding the foreign key +value is nullable. In the following example, when C<$human> is deleted the +related C<$cat> continues to exists and its foreign key value is set to NULL. +See L for details on the +C<< join_type => 'left' >> attribute. + + package My::Schema::Result::Human; + # ... + __PACKAGE__->has_many( + 'cats', + 'My::Schema::Result::Cat', + 'human_id', + { cascade_delete => 0 }, + ); + + package My::Schema::Result::Cat; + # ... + human_id => { + data_type => 'int', + is_numeric => 1, + is_foreign_key => 1, + is_nullable => 1, + }, + # ... + __PACKAGE__->belongs_to( + 'human', + 'My::Schema::Result::Human', + 'human_id', + { join_type => 'left', on_delete => 'SET NULL' }, + ); + =head1 TRANSACTIONS =head2 Transactions with txn_do