[Vienna-pm] Re: Class::DBI pod/doc issues and question for m2m
+might_have
matthias tarasiewicz
parasew at sonance.net
Tue Sep 30 16:23:04 CDT 2003
perrin,
i hope it's not a problem, but i thought it might be nice to reply to
the whole list instead just to you personally.
i finally have the answers to my problems/questions.
for reference, i attached all the important information from the last
mail with my question.
Perrin Harkins wrote:
> On Tue, 2003-09-30 at 14:43, matthias tarasiewicz wrote:
>
>>package FsDBI::User;
>> use base ('FsDBI');
>> __PACKAGE__ ->table ('user');
>> __PACKAGE__ ->columns (Essential => qw(id accountname firstname
>>lastname) );
>> __PACKAGE__ ->has_many (thisismyrole=> ['FsDBI::User::RoleRef' =>
>>'role_id']);
>
>
> You normally need to give an extra argument to has_many that tells it
> which column of the FsDBI::User::RoleRef class to look in. You can
> leave this out when that column has the same name as the current class
> (i.e. "user"), but in this case it doesn't.
>
> __PACKAGE__->has_many (thisismyrole=> ['FsDBI::User::RoleRef' =>
> 'role_id'], 'user_id');
>
> - Perrin
thank you very much. this was the information i was missing to get this
running. this is definitely missing in the POD of Class::DBI!
finally, the follwing was working for my script
#!/usr/bin/perl
use FsDBI;
# retrieve user with id=1
my $test=FsDBI::User->retrieve(1);
print "user ".$test->accountname."\n";
# cycle through all the entries the user has
# and print the diz-field of the entries
foreach my $fugu ($test->UserRoles)
{
print $fugu->diz;
print "\n";
}
Perrin Harkins wrote:
> matthias tarasiewicz wrote:
>> for having a good usage of Class::DBI, as far as i understood it you
>> have to reference the classes the way you want to use them.
>> this means that the has_a and has_many does not need to be the same as
>> your references in the database.
>
> These will only work if you actually have the references in the
> database. All they do is issue SQL queries, so your cd table has to
> have a column holding an artist ID in order for your artist class to do
> a has_many cds. If you're saying that it's not necessary to turn every
> single foreign key into a has_a or has_many, then I agree.
this is what i actually meant.
> Writing good documentation is hard and takes a lot of time. I think the
> Class::DBI docs are quite good. Adding some example SQL tables to go
> along with the music examples in the synopsis sounds like a good idea. I
> think the music example is better than the user/role stuff in your
> examples at the end, because it's more universal.
>
yes, that's a good thing to put the underlying database in the pod,
since things confused me a lot in those examples.
my tables where more to illustrate you my problems, no suggestions for
becoming part of the documentation ;)
>> issues like correct naming of Classes and database-tables become a
>> problem
>
>
> I'm not sure what you mean by this. You can use any class or table name
> you like.
>
see above, i had problems with the mapping as described in the pod since
i did not know much about the database-table names...
> The many-to-many example in the documentation works like this:
>
> 1) Create classes for a CD table, a STYLE table, and a CD_STYLE table
> linking them together.
>
> 2) In your CD class, say it has_many CD_STYLES.
>
> 3) In your CD_STYLES class, say it has_a STYLE.
>
> That's it. Then you can do this:
>
> sub styles {
> my $self = shift;
> return map $_->STYLE, $self->CD_STYLES;
> }
>
> Or you can abbreviate that like this:
>
> Music::CD->has_many(STYLES => [ 'CD_STYLE' => 'STYLE' ]);
>
> The might_have work just like has_a, but it can also import some fields
> from the other object.
>
this plus the last mail you sent me (see above) definitely should go in
the POD! very important since this was the reason why i was mingling
with data for hours (not to say days)
> I agree, a many-to-many method would be useful. If you'd like to try
> writing one, look at the has_many method.
uh, i think this might take some time until i'm ready for that ... ;)
>> for has_a compared to has_many i found it strange that one is
>> depending on correct naming (has_a), the other one completely not.
>
> has_a doesn't depend on naming. You tell it the name of the accessor in
> the current class, and the name of the class to create. They can have
> any names you want. It assumes that the accessor you specify will
> return a value that can be used as the primary key on the class.
>
to some point, it depends on naming (as far as i can tell)
if we take the example you posted on perlmonks
http://perlmonks.org/index.pl?node_id=295176
you have to create a sub for using a has_a with another accessor name
than the key
sub accessor_name {
my ($class, $column) = @_;
$column =~ s/role_id/wild_and_crazy_role/;
return $column;
}
while in has_a you can call the accessor anything you want, because of
the additional argument you can pass:
__PACKAGE__ ->has_many(ihavesomuchroles => 'MyPackage::role','id');
where 'id' would be the id from MyPackage::role
>> # ???
>> # FsDBI::User ->has_many (Roles => ['FsDBI::User::user_role' =>
>> 'role_id']);
>
>
> Yes.
>
>> #???
>> # FsDBI::User::user_role ->has_many(Users =>'FsDBI::User','id');
>
>
> No, has_a, not has_many. This one is not needed if you just want to set
> up $user->roles().
>
>> # FsDBI::User::user_role ->has_many(Roles =>'FsDBI::User::Role',
>> 'id');
>
>
> No, has_a again.
>
> - Perrin
thanks for all the help and greetings,
matthias
--
that's the way i like I.T.
http://fs2.at
-------------- next part --------------
perrin,
first of all thanks for your reply on my first mail.
i am trying for hours now to understand the m:m mapping, but still don't get it running. maybe you can take a look as i am completely lost:
# i have still problems with m:m (many to many) mapping and Class::DBI
# http://search.cpan.org/~tmtm/Class-DBI-0.94/lib/Class/DBI.pm#Mapping
#in a nearby script i call like this
use FsDBI;
my $test=FsDBI::User->retrieve(1);
my @gugu= $test->thisismyrole;
# i always get the error
# Use of 'croak' is deprecated at /usr/lib/perl5/site_perl/5.8.0/Class/DBI.pm line 950.
# Use '_croak' instead is not a column of FsDBI::User::roleref at ./test.pl line 7
# i have this SQL (mysql)
#
# CREATE TABLE user (
# id mediumint(7) NOT NULL auto_increment,
# firstname varchar(25) NOT NULL,
# PRIMARY KEY (id),
# ) Type=MyISAM;
#
# CREATE TABLE user_role (
# entry_id mediumint(7) NOT NULL,
# user_id mediumint(7) NOT NULL,
# role_id smallint(6) NOT NULL,
# ) Type=MyISAM;
#
#
# CREATE TABLE role (
# id smallint(6) NOT NULL auto_increment,
# title varchar(50) NOT NULL,
# diz varchar(50) NOT NULL,
# PRIMARY KEY (id)
# ) Type=MyISAM;
#
# CREATE TABLE entry (
# id mediumint(7) NOT NULL auto_increment,
# txt text,
# PRIMARY KEY (id)
# ) TYPE=MyISAM;default NULL,
# so i am wondering how to make a m:m mapping at least to get
# the roles a user would have.
# i didn't suceed yet.
require DBD::mysql;
use strict;
use warnings;
#require Class::DBI::mysql;
use vars qw($VERSION);
$VERSION = '0.1b';
package FsDBI;
use base ('Class::DBI');
FsDBI->set_db('Main', 'DBI:mysql:dbname', 'user', 'pass');
package FsDBI::User;
use base ('FsDBI');
__PACKAGE__ ->table ('user');
__PACKAGE__ ->columns (Essential => qw(id accountname firstname lastname) );
__PACKAGE__ ->has_many (thisismyrole=> ['FsDBI::User::RoleRef' => 'role_id']);
package FsDBI::User::RoleRef;
use base ('FsDBI');
__PACKAGE__ ->table ('user_role');
__PACKAGE__ ->columns(Essential => qw(user_id role_id));
__PACKAGE__ ->has_a (role_id =>'FsDBI::User::Role');
__PACKAGE__ ->has_a (user_id =>'FsDBI::User');
package FsDBI::User::Role;
use base ('FsDBI');
__PACKAGE__ ->table ('role');
__PACKAGE__ ->columns(Essential => qw( id title diz));
More information about the Vienna-pm
mailing list