[html-formfu] (ping Andreas + zby) Re: DBIC: setting accessor for a
Select element triggers options_from_model()
Carl Franks
fireartist at gmail.com
Thu Apr 3 15:47:04 BST 2008
On 28/02/2008, Zbigniew Lukasiak <zzbbyy at gmail.com> wrote:
> On Wed, Feb 27, 2008 at 11:01 PM, 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?
> >
> > okay, we need to revisit this :(
> >
> > I've moved HTML/FormFu/Model/DBIC.pm out into a separate distribution.
> > $form->model_class() has been renamed to default_model() and no longer
> > defaults to 'DBIC'.
> > (more on that to come in another mail!)
> >
> > However - there's still DBIC-specific code in Element/_Group.pm to
> > handle options_from_model()
> > - this is bad, and needs dealt with.
> >
> > I can see 2 ways to deal with this:
> >
> > 1) Create a new system to provide hooks that model classes can attach
> > to, so the user doesn't need to do anything.
> >
> > 2) Use the hooks provided by the current plugin system, and require
> > the user to specifically add it to the Select field.
> > e.g.
> > ---
> > type: Select
> > name: foo
> > plugins: [ 'DBIC::LoadOptions' ]
> > model_config:
> > DBIC:
> > model: Foo
> >
> > I'm inclined to prefer solution 2, because I foresee the following
> > problems with solution 1:
> > - because we currently don't require the user to load the models in
> > the form config, there's no guarantee that the model will be available
> > during process(), so the hooks won't get run anyway.
> > - adding yet-more hooks will make the formfu internals more complex
> >
> > Any thoughts?
>
>
> Here is my proposal:
>
> sub post_process {
> my $self = shift;
>
> $self->next::method(@_);
>
> my $args = $self->model_config;
>
> # only call options_from_model if there's no options already
> # and {options_from_model} isn't 0
>
> my $option_count = scalar @{ $self->options };
>
> my $option_flag = exists $args->{options_from_model}
> ? $args->{options_from_model}
> : 1;
>
> if ( $option_count == 0 && $option_flag != 0 ) {
> $self->options(
> [ $self->form->model( $args->{model_name}
> )->options_from_model( $self, $args ) ] );
> }
> }
Okay, I can dig that - lets do it!
Do you want to make the necessary changes?
(I'm gonna be off-line for the next week, so won't be able to do it
until after then).
> Minimal change from current. I haven't got any intuition about using
> multiple models in one form - but if we allow for one default model -
> then the last significant line could be:
> [ $self->form->model()->options_from_model( $self, $args ) ] );
>
> The model should know that it is a DBIC model and choose the right
> part of $args passed to it. Or even you could get rid of that level
> in the hash - as it does not really make sense to have both DBIC and
> LDAP options for one field:
>
> - type: Select
> name: type2_id
> model_config:
> DBIC:
> resultset: Type2
> LDAP:
> some_ldap_option: value
>
> Does that make sense? I cannot imagine any situation when this would
> be needed. So I would say just do:
>
> - type: Select
> name: type2_id
> model_config:
> model_name: DBIC
> resultset: Type2
Okay, I don't like it - but I'm inclined to agree that it'll be by far
the most common usage to only use 1 model n any app - so lets make it
easier.
I don't imagine a form updating 2 different models at once, but I can
imagine scenarios where a single element definition might have to be
aware of 2 models.
Andreas - you've been doing some LDAP model work - do you envisage any
problems with different models sharing the same level off of model_config?
If not, lets just go back to that then.
Cheers,
Carl
More information about the HTML-FormFu
mailing list