On 1/17/07, Praveen Ray <[EMAIL PROTECTED]> wrote:
> Thanks. Are you saying, Loader will detect these foreign key based
> relationships and generate methods accordingly - something that
> auto_initialize is not able to do (unless we load the modules in proper
> order)?

It's not about order, it's about loading them at all.  If you just
load a single class (say, Product) that contains an auto_initialize()
call, it's impossible for it to know about any foreign keys that point
to it from other tables because nothing at all is known about any
other tables or classes if only Product.pm is loaded.

If you want to be able to load just Product.pm, which has a simple
call to auto_initialize() in it, *and* you want it to also know about
ProductDetails and MoreProductDetails, then you need to use()
ProductDetails and MoreProductDetails from within Product.pm.

The Loader, on the other hand, will read every table in the database
(by default) and create classes for each one (subject to some
restrictions; see docs).  So the Loader *will* know about all three
tables: products, product_details, and more_product_details.

> The FK is definitely there in the database:
> pg=>\d+ more_product_details
>
> Table "public.more_product_details"
>          Column         |          Type          |
>             Modifiers        | Description
> ------------------------+------------------------+---------------------------------------------------------------------------------------+-------------
>  more_product_detail_id | integer                | not null default
> nextval('more_product_details_more_product_detail_id_seq'::regclass)
> |
>  product_id             | integer                | not null        |
>  product_desc           | character varying(100) |        |
> Indexes:
>     "more_product_details_pkey" PRIMARY KEY, btree (more_product_detail_id)
> Foreign-key constraints:
>     "more_product_details_product_id_fkey" FOREIGN KEY
> (product_id) REFERENCES products(id)
>
> What's the most reliable way to auto-detect such relations (at least simple
> FK based one-many relations)? Or one must 'hand-decorate' the generated code
> always?

What versions of RDBO and Pg are you using?

The Loader should work, and does work here when I try it with Pg 8.2.0
and the latest RDBO.  I created the tables in my database by copying
and pasting the definitions you posted earlier.  Here's the Perl code
I used to test it:

use Rose::DB;
use Rose::DB::Object::Loader;

Rose::DB->register_db(
  driver   => 'Pg',
  database => 'test',
  host     => 'localhost',
  username => 'postgres',
  password => '',
  connect_options => { AutoCommit => 1 },
);

my $db = Rose::DB->new;

my $loader =
  Rose::DB::Object::Loader->new(
    db           => $db,
    class_prefix => 'My::');

my @classes =
  $loader->make_classes(
    include_tables => [ qw(products product_details more_product_details) ]);

foreach my $class (grep { $_->can('meta') } @classes)
{
  print $class->meta->perl_class_definition(braces => 'bsd',
                                            indent => 2), "\n";
}

The code that it prints is included at the end of this email.

-John

---

package My::MoreProductDetail;

use strict;

use base qw(My::DB::Object::AutoBase1);

__PACKAGE__->meta->setup
(
  table   => 'more_product_details',

  columns =>
  [
    more_product_detail_id => { type => 'serial', not_null => 1 },
    product_id             => { type => 'integer', not_null => 1 },
    product_desc           => { type => 'varchar', length => 100 },
  ],

  primary_key_columns => [ 'more_product_detail_id' ],

  foreign_keys =>
  [
    product =>
    {
      class       => 'My::Product',
      key_columns => { product_id => 'id' },
    },
  ],
);

1;

package My::ProductDetail;

use strict;

use base qw(My::DB::Object::AutoBase1);

__PACKAGE__->meta->setup
(
  table   => 'product_details',

  columns =>
  [
    product_detail_id => { type => 'serial', not_null => 1 },
    product_id        => { type => 'integer', not_null => 1 },
    product_name      => { type => 'varchar', length => 100 },
  ],

  primary_key_columns => [ 'product_detail_id' ],

  foreign_keys =>
  [
    product =>
    {
      class       => 'My::Product',
      key_columns => { product_id => 'id' },
    },
  ],
);

1;

package My::Product;

use strict;

use base qw(My::DB::Object::AutoBase1);

__PACKAGE__->meta->setup
(
  table   => 'products',

  columns =>
  [
    id             => { type => 'serial', not_null => 1 },
    product_rating => { type => 'varchar', length => 100 },
  ],

  primary_key_columns => [ 'id' ],

  relationships =>
  [
    more_product_details =>
    {
      class      => 'My::MoreProductDetail',
      column_map => { id => 'product_id' },
      type       => 'one to many',
    },

    product_details =>
    {
      class      => 'My::ProductDetail',
      column_map => { id => 'product_id' },
      type       => 'one to many',
    },
  ],
);

1;

-------------------------------------------------------------------------
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