diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 36b891e11..1c60acf76 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( @@ -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 diff --git a/lib/DBIx/Class/Relationship.pm b/lib/DBIx/Class/Relationship.pm index 26a07ef0e..634b96611 100644 --- a/lib/DBIx/Class/Relationship.pm +++ b/lib/DBIx/Class/Relationship.pm @@ -191,15 +191,11 @@ more info see L. # To retrieve the plain id if you used the ugly version: $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 -right thing. Thus, in the example above C<< $obj->author >> would -return C. However in this case you would probably want to set +If the foreign key column is nullable you 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: +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) __PACKAGE__->belongs_to( @@ -209,7 +205,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.