Re: one to one revisited (has_own)

[prev] [thread] [next] [Date index for 2005/02/01]

From: Peter Speltz
Subject: Re: one to one revisited (has_own)
Date: 17:40 on 01 Feb 2005
Now here is patch i put in AsForm.pm to make inputs automatically for has_one
relationships. This is a work in progress so please speak up if you have any
thoughts or ideas.

Logic to this is : 
If you import columns via has_one then :
 1. Those are only columns you get input boxes for directly in top level cgi
hash. Assumed those are what you need from user to make the object. 
 2. all constraints of relationship get hidden elements made for them with name
and value.

If you don't have imported columns then:
 1. you get a second level hash of all columns inputs in the accessor's slot.
 2. you get hidden inputs in that second level hash.


i'm thinking it may be better to make foreign column names prefix columns with
something so that FromCGI could process them automatically. 

sub to_cgi {
    my $class = shift;
    my %basic = map { $_ => $class->to_field($_) } ($class->columns,
                                                    $class->columns('TEMP')
    );
    # pjs added temp cols. maybe not a good idea. we'll see.
    my %hasones = $class->has_ones_to_cgi;
    return (%basic, %hasones);
}

sub has_ones_to_cgi {
    my $class = shift;
    my %result;
    my $has_ones = $class->meta_info('has_one');

    foreach my $accessor (keys %$has_ones) {
        my $one    = $has_ones->{$accessor};
        my $fclass = $class->get($accessor) || $one->{foreign_class};
        my $predet = $one->{args}->{constraints};
        my $imports= $one->{args}->{'import'};

        # put imported columns directly in primary cgi hash and got to next
        # * so if you import you have to import all ones you want inputs for
        if (@$imports) {
            warn "Making top level elements for improrted columns.";
            foreach (@$imports) {
                next if  $predet->{$_};
                $result{$_} = $fclass->to_field($_) ;
            }
            $result{$_} = $fclass->to_hidden($_, $predet->{$_})
                foreach keys %$predet;
            next; # done with this one  -- maybe shouldn't be
        }
        
        # or put inputs for all cols in second level hash
        my %hash = ();
        foreach (($fclass->columns, $fclass->columns('TEMP'))) {
            next if  $predet->{$_};
            $hash{$_} = $fclass->to_field($_) ;
        }
        $hash{$_} = $fclass->to_hidden($_, $predet->{$_})
            foreach keys %$predet;
        $result{$accessor} = \%hash;
    }
    %result;
}


sub to_hidden {
   my ($self, $name, $val) = @_;
   return HTML::Element->new('input', 'type' => 'hidden',
                              'name' => $name, 'value'=>$val
   );
}

--- Peter Speltz <peterspeltz@xxxxx.xxx> wrote:

> I have a might_have and a has_one (note 'one') relationship ready for
> testing.
> I've given them a little work out. HasOne.pm has a synopsis of using both. I
> chose has_one over has_own. If anyone has a better name i'm all ears. Maybe
> has_own could be an alternative to a has_a relationship as i originally
> thought. Maybe better just to add an extra arg for the meta data instead of 
> making a whole new relationship. Same could be said for has_one and
> might_have
> but since the whole point was to take the "might" out of it a new
> relationship
> seems warranted.
> 
> Here is the synopsis and attached are the files. Except for where i noted
> with
> "# pjs ...", they are both copies of original
> CDBI::Relationship::MightHave.pm.
> Thanks.
> 
> =head1 NAME
> 
> Class::DBI::Relationsip::HasOne -
> 
> Like might_have without the might. Offers a small but significant
> improvement in program readability and CDBI tuning.
> 
> =head1 SYNOPSIS
> 
>     # Example with experimental has_one and might_have
>     # Below not tested but code just like it was.
> 
>     package Music::CD;
> 
>     Music::CD->add_relationship_type(
>         'has_one' => 'Class::DBI::Relationship::HasOne');
> 
>     Music::CD->columns(All => qw/cd_id .../);
> 
>     Music::CDArtist->columns(All =>
>         qw/cd_id artist_type artist_id instrument/);
> 
> 
>     Music::CD->has_one(primary_artist => Music::CDArtist =>
>         qw(artist_id),{_FK_=>'cd_id', artist_type =>'primary'}
>     );
>      
>     Music::CD->might_have(secondary_artist => Music::CDArtist =>
>         qw(), {_FK_=>'cd_id', artist_type => 'secondary'}
>     );
> 
>     Music::CD->might_have(cover_artist => Music::CDArtist =>
>         qw(), {_FK_=>'cd_id', artist_type => 'graphic'}
>     );
> 
>     # Old style should still work
>     Music::CD->might_have(liner_notes => LinerNotes => qw(notes));
> 
>     # And maybe a new has_many style that takes limiters ?
>     Music::CD->has_many(band_members => Music::CDArtist,
>         {   _FK_ => 'cd_id', order_by => 'instrument',
>             artist_type => 'band_member'
>         }
>     );
> 
>     # And to make it all worth while . . .
>     sub create_new {
>         my $self = shift;
>         my $req_components = $self->meta_info('has_one');
>         my $opt_components = $self->meta_info('might_have');
> 
>         my %cgi = $self->to_cgi; # get inputs from AsForm
>         foreach my $comp (keys %$req_components) {
>             my $fclass = $req_components->{$comp}->{foreign_class};
>             $cgi{$comp} = $fclass->to_cgi;
>         }
> 
>         my $template_args = {
>             cgi => $cgi,
>             opt_components => $opt_components
>         };
>     }
> 
>     # ... accessing in TT templates
>     [% cd.primary_artist; %]
>     [% cd.secondary_artist;%]
>     [% flute_players = cd.band_members('instrument' , 'flute')%]
> 
> 
>     # A Comparison:  do above with with just a has_many
>     ...
>     Music::CD->has_many(artists => "Music::CDArtist");
>     ...
>     sub create_new_cd {
>         my $self->shift;
>         my $required_components = ;
>         # This isn't fun anymore.
>     }
> 
>     # accessing in TT templates
>     [% primary = cd.artists('artist_type' , 'primary');
>        # hopefully %]
>     [% secondary  = cd.artists('artist_type' , 'secondary')%]
>     [% flute_players = cd.artists('instrument' , 'flute')%]
> 
> =====
> pjs
> 
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around 
> http://mail.yahoo.com 

> ATTACHMENT part 2 application/x-perl name=MightHave.pm


> ATTACHMENT part 3 application/x-perl name=HasOne.pm



=====
pjs

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

(message missing)

one to one relationship revisited (has_own)
Peter Speltz 22:26 on 20 Jan 2005

Re: one to one relationship revisited (has_own)
Perrin Harkins 21:59 on 21 Jan 2005

Re: one to one relationship revisited (has_own)
Peter Speltz 05:11 on 22 Jan 2005

Re: one to one revisited (has_own)
Peter Speltz 18:16 on 22 Jan 2005

Re: one to one revisited (has_own)
William McKee 15:39 on 24 Jan 2005

Re: one to one revisited (has_own)
Peter Speltz 16:01 on 24 Jan 2005

Re: one to one revisited (has_own)
Andreas Fromm 08:19 on 25 Jan 2005

Re: one to one revisited (has_own)
Peter Speltz 19:34 on 25 Jan 2005

Selecting from a datetime field in MySQL
John Day 22:24 on 25 Jan 2005

Re: Selecting from a datetime field in MySQL
Perrin Harkins 22:29 on 25 Jan 2005

Re: one to one revisited (has_own)
Peter Speltz 23:24 on 26 Jan 2005

Re: one to one revisited (has_own)
Peter Speltz 17:40 on 01 Feb 2005

Re: one to one revisited (has_own)
Peter Speltz 08:23 on 25 Jan 2005

Generated at 12:39 on 05 Feb 2005 by mariachi v0.52