Index: /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/t/update/many_to_many_select.t
===================================================================
--- /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/t/update/many_to_many_select.t (revision 1493)
+++ /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/t/update/many_to_many_select.t (working copy)
@@ -1,6 +1,6 @@
use strict;
use warnings;
-use Test::More tests => 5;
+use Test::More tests => 13;
use HTML::FormFu;
use lib 't/lib';
@@ -39,6 +39,9 @@
# band 3 - not used
$schema->resultset('Band')->create({ band => 'the kinks' });
+ # band 4 - not used
+ $schema->resultset('Band')->create({ band => 'the hoorays' });
+
# band 1
$u2->add_to_bands($band1);
}
@@ -75,3 +78,66 @@
is( $id[1], 3 );
}
+# additive
+
+$form = HTML::FormFu->new;
+
+$form->load_config_file('t/update/many_to_many_select_additive.yml');
+
+$form->stash->{schema} = $schema;
+
+{
+ $form->process( {
+ id => 2,
+ name => 'Paul McCartney',
+ bands => 2,
+ } );
+
+ ok( $form->submitted_and_valid );
+
+ my $row = $schema->resultset('User')->find(2);
+
+ $form->model->update($row);
+}
+
+{
+ my $row = $schema->resultset('User')->find(2);
+
+ is( $row->name, 'Paul McCartney' );
+
+ my @bands = $row->bands->all;
+
+ is( scalar @bands, 3 );
+
+ my @id = sort map { $_->id } @bands;
+
+ is_deeply( \@id, [qw(1 2 3)] );
+}
+
+{
+ $form->process( {
+ id => 2,
+ name => 'Paul McCartney',
+ bands => [qw(1 2 3 4)],
+ } );
+
+ ok( $form->submitted_and_valid );
+
+ my $row = $schema->resultset('User')->find(2);
+
+ $form->model->update($row);
+}
+
+{
+ my $row = $schema->resultset('User')->find(2);
+
+ is( $row->name, 'Paul McCartney' );
+
+ my @bands = $row->bands->all;
+
+ is( scalar @bands, 4 );
+
+ my @id = sort map { $_->id } @bands;
+
+ is_deeply( \@id, [qw(1 2 3 4)] );
+}
\ No newline at end of file
Index: /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/t/update/many_to_many_select_additive.yml
===================================================================
--- /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/t/update/many_to_many_select_additive.yml (revision 0)
+++ /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/t/update/many_to_many_select_additive.yml (revision 0)
@@ -0,0 +1,19 @@
+---
+auto_fieldset: 1
+
+elements:
+ - type: Hidden
+ name: id
+
+ - type: Text
+ name: name
+
+ - type: Select
+ name: bands
+ multiple: 1
+ model_config:
+ additive: 1
+ options_from_model: 0
+
+ - type: Submit
+ name: submit
Index: /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/lib/HTML/FormFu/Model/DBIC.pm
===================================================================
--- /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/lib/HTML/FormFu/Model/DBIC.pm (revision 1493)
+++ /Users/mo/Documents/workspace/HTML-FormFu-Model-DBIC/lib/HTML/FormFu/Model/DBIC.pm (working copy)
@@ -61,7 +61,7 @@
my ( $self, $base, $attrs ) = @_;
$attrs = $attrs ? _compatible_attrs($attrs) : {};
-
+
my $form = $base->form;
my $resultset = _get_resultset( $base, $form, $attrs );
my $source = $resultset->result_source;
@@ -121,14 +121,13 @@
if ( defined $schema ) {
my $rs_name = $attrs->{resultset} || ucfirst $base->name;
-
return $schema->resultset($rs_name);
}
elsif ( defined $context && defined $attrs->{model} ) {
my $model = $context->model( $attrs->{model} );
- if ( defined( my $rs = $attrs->{resultset} ) ) {
+ if ( defined( my $rs = $attrs->{resultset} || ucfirst $base->name ) ) {
$model = $model->resultset( $rs );
}
@@ -817,7 +816,7 @@
sub _save_multi_value_fields_many_to_many {
my ( $base, $dbic, $form, $attrs, $rels, $cols ) = @_;
-
+
my @fields = grep {
( defined $attrs->{nested_base} && defined $_->parent->nested_name )
? $_->parent->nested_name eq $attrs->{nested_base}
@@ -843,12 +842,13 @@
my @values = $form->param_list($nested_name);
my @rows;
- if (@values) {
- my $config = _compatible_config($field);
+ my $config = _compatible_config($field);
- my ($pk) = $config->{default_column}
- || $related->result_source->primary_columns;
+ my ($pk) = $config->{default_column}
+ || $related->result_source->primary_columns;
+ if (@values) {
+
$pk = "me.$pk" unless $pk =~ /\./;
@rows = $related->result_source->resultset->search( {
@@ -856,9 +856,23 @@
$pk => { -in => \@values } } )->all;
}
- my $set_method = "set_$name";
-
- $dbic->$set_method( \@rows );
+ if($config->{additive}) {
+
+ $pk =~ s/^.*\.//;
+
+ my $set_method = "add_to_$name";
+
+ my @current = map { $_->$pk } $related->all;
+
+ foreach my $row ( @rows ) {
+ next if grep { $_ eq $row->id } @current;
+ $dbic->$set_method($row);
+ }
+ } else {
+ my $set_method = "set_$name";
+
+ $dbic->$set_method( \@rows );
+ }
}
}
}
@@ -1356,7 +1370,23 @@
model_config:
default_column: foo
+The default implementation will first remove all related objects and set the
+new ones (see L).
+If you want to add the selected objects to the current set of objects
+set C in the C.
+ ---
+ element:
+ - type: Checkboxgroup
+ name: authors
+ model_config:
+ additive: 1
+ options_from_model: 0
+
+( is set to C<0> because this L will try to fetch
+all objects from the result class C if C is specified
+without a C attribute.)
+
=head1 COMMON ARGUMENTS
The following items are supported in the optional C hash-ref argument