[html-formfu] How to restrict retrieved rows in has_many relationships?

michele.gherlone at liceoberchet.it michele.gherlone at liceoberchet.it
Thu Aug 6 18:04:01 GMT 2009


> Moritz Onken schrieb:
>>
>> Am 06.08.2009 um 08:42 schrieb Mario Minati:
>>
>>> michele.gherlone at liceoberchet.it schrieb:
>>>>> michele.gherlone at liceoberchet.it schrieb:
>>>>>
>>>>>>> Hi Michele,
>>>>>>>
>>>>>>> currently I don't think this is possible in the dynamic way you
>>>>>>> want
>>>>>>> it.
>>>>>>>
>>>>>>> What I don't understand is that materia is a underneath voti. If
>>>>>>> materia
>>>>>>> shall control the elements of voti, it should be at least on the
>>>>>>> same
>>>>>>> hierarchical level.
>>>>>>>
>>>>>>>
>>>>>> Hi, Mario. I didn't explain my relationships in detail, maybe.
>>>>>> Since table materia has_many voti, and table studente has_many
>>>>>> voti, in
>>>>>> the 'voti' table we have studente_id and materia_id. In the config
>>>>>> file
>>>>>> I
>>>>>> showed you, I am exploiting in the last Block underneath voti the
>>>>>> belongs_to relationship (voto belongs_to materia, materia_id). The
>>>>>> column
>>>>>> I'd like to restrict my results with would also be materia_id.
>>>>>>
>>>>>> I think I could also try to use a multi like a select or a
>>>>>> checkboxgroup
>>>>>> with options_from_ model, but again I should then set:
>>>>>> model_config:
>>>>>> resultset: Voto
>>>>>> condition:
>>>>>>  materia_id: 2
>>>>>>  studente_id: 2315
>>
>> I would propose something like this:
>>
>> $element->model_config->{condition} = sub { my ($form, $element) = @_;
>> return { materia_id => 2, studente_id => 1234 } }
>>
>> This would allow you to set the materia_id or studente_id dynamically
>> by iterating through the $form/$element tree.
>>
>> moritz
>
> What I understood is, that materia_id and studente_id are dependend on
> the values of fields on level up in the element tree (so the value from
> outside the repeatable which is also a repeatable).
>
> So it's rather dynamic.
>
> This is probably an other repeated inside repeated problem, as we always
> pick all elements from a related table and don't use something like
> search_related. But I might be wrong. The Model::DBIC class is hard to
> understand.

Hi Mario!
After a bit of hacking with a friend of mine, I came to the following
(certainly temporary) solution of my feature:

--- DBIC.pm.old 2009-08-06 18:37:53.000000000 +0200
+++ DBIC.pm     2009-08-06 19:31:30.000000000 +0200
@@ -151,7 +151,7 @@
 }

 sub default_values {
-    my ( $self, $dbic, $attrs ) = @_;
+    my ( $self, $dbic, $attrs, $search_related_attrs ) = @_;

     $attrs = $attrs ? _compatible_attrs($attrs) : {};

@@ -164,7 +164,7 @@
                 || $base->nested_name ne $attrs->{nested_base} );

     _fill_in_fields( $base, $dbic );
-    _fill_nested( $self, $base, $dbic );
+    _fill_nested( $self, $base, $dbic, $search_related_attrs );

     return $form;
 }
@@ -258,7 +258,7 @@
 # loop over all child blocks with nested_name that is a method on the
DBIC row
 # and recurse
 sub _fill_nested {
-    my ( $self, $base, $dbic ) = @_;
+    my ($self,$base,$dbic,$search_related_attrs)=@_;

     for my $block ( @{ $base->get_all_elements } ) {
         next if $block->is_field && !$block->is_block;
@@ -304,9 +304,19 @@
                 $pk eq
                     ( defined $_->original_name ? $_->original_name :
$_->name )
                 } @{ $block->get_fields( { type => 'Hidden' } ) };
-
-            my @rows = $dbic->$rel->all;
-
+
+            my $nested_name;
+            for (@{$search_related_attrs}) {
+              $nested_name=$_ if ($rel eq $_->{nested_name});
+            }
+
+            my @rows;
+            if ($nested_name) {
+              @rows = $dbic->search_related($rel,
$nested_name->{condition})->all;
+            } else {
+              @rows = $dbic->$rel->all;
+            }
+
             my $count = $config->{empty_rows}    ? scalar @rows +
$config->{empty_rows}
                       : $config->{new_empty_row} ? scalar @rows + 1
                       :                            scalar @rows;
@@ -317,7 +327,7 @@

             for my $rep ( 0 .. $#rows ) {
                 default_values( $self, $rows[$rep],
-                    { base => $blocks->[$rep] } );
+                    { base => $blocks->[$rep] }, $search_related_attrs );
             }

             # set the counter field to the number of rows

This way I can call $form->model->default_values($dbic, {},
[{nested_name=>'voti', condition=>{materia_id=>$materia_id}}])
The 3rd argument to default_values would also become an arrayref of
hashrefs each containing two keys: nested_name and condition, this latter
passed as is to search_related (line 315 of the patched DBIC.pm).
What I really want here is NOT having the config file dynamically set the
search condition, but I want the search condition to be set in the
Catalyst controller itself, coming from a user's choice. I don't know
whether this feature will be of such an interest to be implemented in HF
definitely, but it is indeed useful and makes no harm if not implemented
at all. We tested our patched DBIC.pm and it just works great.
Greets,
Michele

> _______________________________________________
> HTML-FormFu mailing list
> HTML-FormFu at lists.scsys.co.uk
> http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu
>





More information about the HTML-FormFu mailing list