[Dbix-class] DBIx::Class many_to_many problems

fREW Schmidt frioux at gmail.com
Sat Jul 11 21:31:12 GMT 2009


On Sat, Jul 11, 2009 at 3:15 PM, Shawn Marincas <shawngmarincas at gmail.com>w=
rote:

> Hello, I'm having a trouble accessing resultsets through a many-to-many
> relationship defined by my schema.  I have a products table and a categor=
ies
> table that are related many-to-many so that products can be in multiple
> categories.  This is the example they give in the
> DBIx::Class::Manual::Cookbook for a straightforward configuration using
> ManyToMany is:
>
>   package My::User;
>   use base 'DBIx::Class';
>   __PACKAGE__->load_components('Core');
>   __PACKAGE__->table('user');
>   __PACKAGE__->add_columns(qw/id name/);
>   __PACKAGE__->set_primary_key('id');
>
>
>
>   __PACKAGE__->has_many('user_address' =3D> 'My::UserAddress', 'user');
>   __PACKAGE__->many_to_many('addresses' =3D> 'user_address', 'address');
>
>   package My::UserAddress;
>
>
>
>   use base 'DBIx::Class';
>   __PACKAGE__->load_components('Core');
>   __PACKAGE__->table('user_address');
>   __PACKAGE__->add_columns(qw/user address/);
>   __PACKAGE__->set_primary_key(qw/user address/);
>
>
>
>   __PACKAGE__->belongs_to('user' =3D> 'My::User');
>   __PACKAGE__->belongs_to('address' =3D> 'My::Address');
>
>   package My::Address;
>   use base 'DBIx::Class';
>
>
>
>   __PACKAGE__->load_components('Core');
>   __PACKAGE__->table('address');
>   __PACKAGE__->add_columns(qw/id street town area_code country/);
>   __PACKAGE__->set_primary_key('id');
>
>
>
>   __PACKAGE__->has_many('user_address' =3D> 'My::UserAddress', 'address');
>   __PACKAGE__->many_to_many('users' =3D> 'user_address', 'user');
>
>   $rs =3D $user->addresses(); # get all addresses for a user
>
>
>
>   $rs =3D $address->users(); # get all users for an address
>
>
>
> Here is my configuration:
>
> package MyAppDB::Product;
>
> use base qw/DBIx::Class/;
>
> __PACKAGE__->load_components(qw/PK::Auto Core/);
> __PACKAGE__->table('Products');
> __PACKAGE__->add_columns(qw/product_id name sku vendor_id price height
> width depth diameter color weight description info img_thumb img_large
> date_added shipping availability is_favorite importance/);
> __PACKAGE__->set_primary_key(qw/product_id/);
>
> # Vendor relationship
> __PACKAGE__->belongs_to(vendor =3D> 'MyAppDB::Vendor', 'vendor_id');
>
> # Category many-to-many relationship
> __PACKAGE__->has_many('product_categories' =3D>
> 'MyAppDB::ProductCategoryLink', 'product_id');
> __PACKAGE__->many_to_many('categories' =3D> 'product_categories',
> 'category_id');
>
> 1;
>
> package MyAppDB::ProductCategoryLink;
>
> use base qw/DBIx::Class/;
>
> __PACKAGE__->load_components(qw/PK::Auto Core/);
> __PACKAGE__->table('ProductCategoryLink');
> __PACKAGE__->add_columns(qw/product_id category_id/);
> __PACKAGE__->set_primary_key(qw/product_id category_id/);
>
> # belongs_to():
> __PACKAGE__->belongs_to(product =3D> 'MyAppDB::Product', 'product_id');
>
> # belongs_to():
> __PACKAGE__->belongs_to(category =3D> 'MyAppDB::Category', 'category_id');
>
> 1;
>
>
> package MyAppDB::Category;
>
> use base qw/DBIx::Class/;
>
> __PACKAGE__->load_components(qw/PK::Auto Core/);
> __PACKAGE__->table('Categories');
> __PACKAGE__->add_columns(qw/category_id name/);
> __PACKAGE__->set_primary_key(qw/category_id/);
>
>
> # Category many-to-many relationship
> __PACKAGE__->has_many('product_categories' =3D>
> 'MyAppDB::ProductCategoryLink', 'category_id');
> __PACKAGE__->many_to_many('products' =3D> 'product_categories', 'product'=
);
>
> 1;
>
>
> In my Catalyst controller I try and access all the Products of a given
> Category like so:
>
>        $c->stash->{products} =3D [$c->model('MyAppDB::Category')->search({
> name =3D> $category })->products];
>
> And receive the following error:
>
> "Can't locate object method "products" via package "DBIx::Class::ResultSe=
t"
>
>
> I am using Catalyst 5.80007 on CentOS 5.0 x64 with MySQL 14.12... I have
> setup the database tables with the InnoDB engine and setup the foreign ke=
ys
> in the link table.  I don't know what else I could be missing here... any=
one
> have ideas where I could be going wrong?  I'm a relatively new user of bo=
th
> Catalyst and DBIx::Class.  Thanks so much.
>
> - Shawn Marincas


It's because you are doing a search, which returns a resultset, and you are
using products, which would be chained off of the category class.  You
probably want to do something like this:

 $c->stash->{products} =3D [$c->model('MyAppDB::Category')->single({ name =
=3D>
$category })->products];

That will return the first (and presumably only) category that has the name
you passed in.  If you do have more than one category with that name you
will get an error.  In that case you could say first instead of single.

HTH
-- =

fREW Schmidt
http://blog.afoolishmanifesto.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/dbix-class/attachments/20090711/3cb=
ddec6/attachment.htm


More information about the DBIx-Class mailing list