(Oops, accidentally sent an imcomplete message last time
On 8/5/06 9:44 AM, Danial Pearce wrote:
> On 8/5/06, John Siracusa <[EMAIL PROTECTED]> wrote:
>> I've rearranged the interface to this stuff a little bit in SVN, but
>> the results should still take care of your situation. If you get a
>> chance, try the SVN version and let me know if it correctly makes the
>> foo->bar relationship "optional" by default.
>
> Mine is dying when you have a completely new object, and you have your
> new object to create a new object in the relationship also.
Cascade on save really doesn't come into play with brand new objects.
They're handled by the existing get_set_on_save methods.
> Consider the following tables:
>
> 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
);
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.)
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.
-John
-------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rose-db-object