[html-formfu] DBIC: setting accessor for a Select element triggers options_from_model()

Carl Franks fireartist at gmail.com
Fri Feb 22 16:24:06 GMT 2008


On 22/02/2008, Carl Franks <fireartist at gmail.com> wrote:
> On 22/02/2008, Andreas Marienborg <omega at palle.net> wrote:
>  >
>  >  On Feb 22, 2008, at 12:08 PM, Carl Franks wrote:
>  >
>  >  > On 21/02/2008, Steve Caldwell <info-formfu at caldwellhb.com> wrote:
>  >  >> I'm building a form that has a Select element that I'm mapping to a
>  >  >> non-column accessor on my DBIC object, as described in "non-column
>  >  >> accessors" in the HTML::FormFu::Model::DBIC POD, like this:
>  >  >>
>  >  >> ---
>  >  >> action: /foo
>  >  >> elements:
>  >  >>  - type: Select
>  >  >>    name: bar
>  >  >>    label: Your Bar
>  >  >>    db:
>  >  >>      accessor: bar
>  >  >>    options:
>  >  >>      - [ 01, January ]
>  >  >>      - [ 02, February ]
>  >  >>
>  >  >> When I then try and populate it from my DBIC object:
>  >  >>
>  >  >> $form->defaults_from_model( $myobj );
>  >  >>
>  >  >> HTML::FormFu::Model::DBIC::options_from_model gets called (thanks to
>  >  >> line 44 in HTML::FormFu::Element::_Group), which then overwrites the
>  >  >> options I've set from my select list with a bunch of stuff from the
>  >  >> database.  This is obviously not what I want here.
>  >  >>
>  >  >> Anyone else come across this problem?  The work-around isn't that
>  >  >> much
>  >  >> work (manually populate from and save to my object instead of using
>  >  >> defaults_from_model() and save_to_model()), but it would be cooler
>  >  >> if it
>  >  >> all worked correctly.
>  >  >
>  >  > I agree that this is broken.
>  >  > I think Select automatically calling options_from_model() is a case of
>  >  > *too much magic*
>  >  >
>  >  > (sidenote) - I know you've only just subscribed to the list, so a
>  >  > quick explanation, so that you understand my following proposal:
>  >  > FormFu in svn has been changed so that you set Model/DBIC options
>  >  > with:
>  >  >    $field->{model_config}{DBIC}
>  >  > instead of:
>  >  >    $field->{db}
>  >  >
>  >  > This will be in the next cpan release. However, setting {db} will
>  >  > still work, and Do The Right Thing, it'll just print a warning that
>  >  > it's deprecated and will be removed at some point in the future.
>  >  >
>  >  > The reason for this, is the model was implemented as a bit of a
>  >  > rush-job and we need to get it working properly to support multiple
>  >  > models - much like how Catalyst handles models.
>  >  > (/sidenote)
>  >  >
>  >  > I suggest we require that a new option be set to run
>  >  > options_from_model(), such as:
>  >  >
>  >  >    ---
>  >  >    element:
>  >  >      type: Select
>  >  >      name: foo
>  >  >        model_config:
>  >  >          DBIC:
>  >  >            options_from_model: 1
>  >  >
>  >  > (or, in the old, deprecated, style):
>  >  >
>  >  >    ---
>  >  >    element:
>  >  >      type: Select
>  >  >      name: foo
>  >  >        db:
>  >  >          options_from_model: 1
>  >  >
>  >  > Any opinions on this?
>  >
>  >
>  > Could the default be to run it if:
>  >
>  >  - no options_from_model: 0 (false) exists
>  >  AND
>  >  - no options already set on the select?
>
>
> Hmm, yes - I suppose that any options should have already been added
>  before $form->process() is called - so if there's no select options
>  yet, we can take that as a hint that a little magic might be
>  appropriate.
>
>  I think I could go for that.
>
>  However, it means that _Group needs a new accessor to return the
>  current option list.
>  Some tests delve into {_options}, but that's unacceptable for core
>  code outside of _Group.pm

okay, I've modified _Group::options() so that if it's not passed any
arguments, it acts as a getter, and returns an arrayref of the current
options.

I've also implemented the change to the calling of options_from_model,
as described above.

So this should be backwards compatible, except in the case that
someone's added options already, yet still wants options_from_model()
to automatically be run. If that's the case, you'll need to add
"options_from_model: 1" to your config.

Cheers,
Carl



More information about the HTML-FormFu mailing list