> > create table foo ( id serial not null, foo text );
> > create table bar ( foo_id int not null references foo(id), bar text);
>
> Neither has a primary key, and RDBO requires every table to have one.  But
> I'll assume you meant this:
>
>   create table foos
>   (
>     id serial not null primary key,
>     foo text
>   );
>
>   create table bars
>   (
>     foo_id int not null primary key references foos (id),
>     bar text
>   );

Apologies. You are correct. I did mean to have primary key on those.

> Given those tables, this is what the Loader makes of them:
>
>   package Bar;
>   ...
>   __PACKAGE__->meta->setup
>   (
>     table   => 'bars',
>     columns =>
>     [
>       foo_id => { type => 'integer', not_null => 1 },
>       bar    => { type => 'text' },
>     ],
>
>     primary_key_columns => [ 'foo_id ' ],
>
>     foreign_keys =>
>     [
>       foo =>
>       {
>         class => 'Foo',
>         key_columns => { foo_id => 'id' },
>       },
>     ],
>   );
>
>   package Foo;
>   ...
>   __PACKAGE__->meta->setup
>   (
>     table   => 'foos',
>     columns =>
>     [
>       id  => { type => 'serial', not_null => 1 },
>       foo => { type => 'text' },
>     ],
>
>     primary_key_columns => [ 'id' ],
>
>     relationships =>
>     [
>       bars =>
>       {
>         class       => 'Bar',
>         key_columns => { id => 'foo_id' },
>         type        => 'one to many',
>       },
>     ],
>   );
>
> Notice that it's made the foo->bar relationship a one-to-many.  It's not
> quite smart enough to see that both foo.id and bar.foo_id are unique keys
> (primary keys, in fact), making it a one-to-one relationship.
>
> I've updated the Loader in SVN to correctly detect one-to-one relationships,
> so now it produces a Foo class like this:
>
>   package Foo;
>   ...
>   __PACKAGE__->meta->setup
>   (
>     table   => 'foos',
>     columns =>
>     [
>       id  => { type => 'serial', not_null => 1 },
>       foo => { type => 'text' },
>     ],
>
>     primary_key_columns => [ 'id' ],
>
>     relationships =>
>     [
>       bar =>
>       {
>         class      => 'Bar',
>         column_map => { id => 'foo_id' },
>         type       => 'one to one',
>       },
>     ],
>   );
>
> (Note that I changed "key_columns" to "column_map" too.)

I was using add_relationships() to manually set my type to "one to
one" anyway. I was also using column_map.

> Now for the code:
>
>   my $bar = Bar->new;
>   my $foo = Foo->new;
>   $foo->bar($bar);
>   $foo->bar->bar('some text');
>   $foo->save;
>
> This now runs successfully, executing the following SQL:
>
>   # Save the foo row
>   INSERT INTO foos (foo, id) VALUES (NULL, 1);
>
>   # Check to see if $bar already exists in the database.
>   # (In this case, it doesn't.)
>   SELECT bar, foo_id FROM bars WHERE foo_id = 1
>
>   # Add the bar row
>   INSERT INTO bars (bar, foo_id) VALUES ('some text', 1);
>
> Notice that the "cascade" flag is not used at all.  If it were added:
>
>   $foo->save(cascade => 1);
>
> it would not alter the SQL at all, nor would it add any more queries.  It
> would, however, check to see if $bar has unsaved changes.  It doesn't (it
> was just saved) so $bar does not need to be (re)save()d.

Yep, works for me now too. Thanks a bunch!

I also tested your fix for not running the UPDATE sql where there were
no fields to update, and it is also work a treat. Thanks again.

-- 
"Cats are smarter than dogs. You can't get eight cats to pull a sled
through snow." - Jeff Valdez

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to