Subject: | allowing scalar values for has_many updates |
The following is NOT a bug!
It is a feature which makes cooperation of RecursiveUpdate with
HTML::FormHander (and maybe other modules) more easy to set up.
At the moment, recursive_update expects all update-parameters to be
hashrefs. This is almost always good, except one case:
It would be possible to use scalar values as updates for has_many
relations, IF the related resultsource has EXACTLY one primary key.
In this case, recursive_update can know how to use the single scalar
value and build the corresponding hash by itself.
Why is this usefull? Because:
HTML::FomHander::Model::DBIC (and maybe other modules) return a list of
scalar values (selected ids) when multiple items are selected in a
select-field. Because this list can not be passed to recursive_update
(because it contains scalars, and no hashes), it is not possible to use
HTML::FormHander to update has_many relations.
I have created a patch which solves the problem by transforming the
updates-variable from
'SCALAR_VALUE' to
{ primary_key_name => 'SCALAR_VALUE' }
IF the current relation is a has_many-relation AND the $updates variable
stores a scalar AND the related resultsource has exactly one primary column.
I also thought about solving the problem in HTML::FormHander, but I
thougt that RecursiveUpdate is the better place to fix this issue.
My reasons are:
1. IF the related source has exactly one primary column, the primary
columns value is enough to identify the coresponding object/row
2. It is easy to fix the problem within RecursiveUpdate and (a little)
more complicated in HTML::FormHander
3. The patch does not change RecursiveUpdates behaviour, it just fixes
unexpected data instead of throwing an exception. This change of
input-data is always safe.
4. Fixing the issue in RecursiveUpdate solves the problem for
HTML::FormHander, and any other module which uses RecursiveUpdate, now
and in the future.
I would be very glad to see this feature in future releases of
DBIx::Class::ResultSet::RecursiveUpdate
kind regards, lukast
Subject: | recursiveupdate_hasmany_scalarupdates.patch |
--- DBIx/Class/ResultSet/RecursiveUpdate.pm 2011-02-08 15:39:12.000000000 +0100
+++ DBIx/Class/ResultSet/RecursiveUpdate.pm.request.patched 2011-02-08 16:14:36.000000000 +0100
@@ -353,6 +353,24 @@
#warn "\tupdating has_many rel '$name' ($rel_col_cnt columns cols)\n";
for my $sub_updates ( @{$updates} ) {
+ unless ( ref($sub_updates) eq 'HASH') {
+ # sub_updates is a scalar
+ if((not ref($sub_updates)) or ref($sub_updates) eq 'SCALAR'){
+ my @primary_cols = $related_resultset->result_source->primary_columns;
+ # related result has EXACTLY one primary column
+ if(@primary_cols == 1){
+ # "hashify" updates
+ $sub_updates = {$primary_cols[0] => $sub_updates};
+ }
+ else{
+ croak "$name has more than one primary column, and sub_updates is not a HASH";
+ }
+ }
+ else{
+ croak "updates for $name has to be a HASH or a single SCALAR";
+ }
+
+ }
my $sub_object = recursive_update(
resultset => $related_resultset,
updates => $sub_updates,