Re: [Catalyst] Model objects from multiple DBIx::Class rows
Hi Stephen, As far as I know, creating result class without underlying table is not supported. Having a class without table, but with relationships doesn't realy make sense to me. A relationship always has two sides. I am not sure if I really understand your problem. You have a user table and a related picture table? My approach would be to select the user from the user-table, and use prefetch to populate the pictures-relation with the same call. You will get a $user object with the pictures relationship already populated. https://metacpan.org/module/DBIx::Class::ResultSet#prefetch If you want to update several related tables with a single method call, take a look at RecursiveUpdate. It is not the fastest solution, and there might be situations where it is not suitable, but it works fine in most cases. And it allows you to pass nested hash- and arrayrefs to recursive_update, and therefore updating or creating several related rows with very little code. For example, HTML::FormHandler uses R-U to update the database. https://metacpan.org/module/DBIx::Class::ResultSet::RecursiveUpdate It is also possible to create several result classes for the same table, if you need different behavior in different situations. You cound, for example, create a Montage class, which works on the user table, and add custom code which is only needed by montages. The old user class will still be available. cheers, Lukas On 11/22/2012 04:59 PM, Stephen Shorrock wrote: Hi, I was wondering whether there is any advice out there about how to use and manage objects within a Catalyst application where the objects contain DBIx::Class schema model objects that are also within the application. I've considered creating simple moose objects that get passed the schema objects and use rows returned from the schema objects to populate 'local' values but this doesn't seem right. The trouble I have is that data for these objects is stored in the database but their i sno single table for the object them selves for example I might have a Montage object that has a $User and several @Pictures the User record is stored in the database and the Picture records are also stored as individual rows in a pictures table. I want to manipulate the users along with their pictures as an object them selves, for example given a User DBIx::class objects create a method (eg get_montage) that returns a Montage. Is there a simple solution perhaps creating a DBIx::class object that doesn't actually have an underlying table but can still utilize relationships and have User::get_montage return an instance of one of these? Or am I overlooking something else that is obvious? Thanks in advance Stephen ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Model objects from multiple DBIx::Class rows
Hi Lukas, Firstly thanks and secondly I take your point regarding the relationships. It seems sensible that I should create an object to manipulate a Montage rather than methods attached to other objects that seem to be modifying something virtual. For example a Montage might have a period associated to it so when I display the details the Montage knowing it's period can identify the pictures from it's period containing the user that belong to it and maybe on a picture rating set by the user include them to be displayed. To always have to pass start and end dates, and perhaps other Montage related attributes, to a method in the users object doesn't see right. Ideally I would wish for the Montage object to have access to all the objects in the schema where the Montage object can call the CRUD methods to modify its underlying state. Does this seem any clearer? The best way I have at the moment is to have a plain Moose Montage object that is passed the User object at initialization. It then can go away and from the User object and it's relationships populate the pictures array/resultset, all the montage methods are later at hand to manipulate for views / controlelrs etc. I can't put my finger on it but at the moment something seems slightly amiss with needing the dependencies between the plain Moose object and a DBIx::Class schema object. My feeling is that they don't really need to exist because without the specific schema it's unlikely that the Montage class would exist in the same form, and that everything should be in the same package. I think that it must be something very basic that I've overlooking, perhaps in terms of where the class should be located. Stephen On Thu, Nov 22, 2012 at 4:33 PM, Lukas Thiemeier spamcatc...@thiemeier.net wrote: Hi Stephen, As far as I know, creating result class without underlying table is not supported. Having a class without table, but with relationships doesn't realy make sense to me. A relationship always has two sides. I am not sure if I really understand your problem. You have a user table and a related picture table? My approach would be to select the user from the user-table, and use prefetch to populate the pictures-relation with the same call. You will get a $user object with the pictures relationship already populated. https://metacpan.org/module/DBIx::Class::ResultSet#prefetch If you want to update several related tables with a single method call, take a look at RecursiveUpdate. It is not the fastest solution, and there might be situations where it is not suitable, but it works fine in most cases. And it allows you to pass nested hash- and arrayrefs to recursive_update, and therefore updating or creating several related rows with very little code. For example, HTML::FormHandler uses R-U to update the database. https://metacpan.org/module/DBIx::Class::ResultSet::RecursiveUpdate It is also possible to create several result classes for the same table, if you need different behavior in different situations. You cound, for example, create a Montage class, which works on the user table, and add custom code which is only needed by montages. The old user class will still be available. cheers, Lukas On 11/22/2012 04:59 PM, Stephen Shorrock wrote: Hi, I was wondering whether there is any advice out there about how to use and manage objects within a Catalyst application where the objects contain DBIx::Class schema model objects that are also within the application. I've considered creating simple moose objects that get passed the schema objects and use rows returned from the schema objects to populate 'local' values but this doesn't seem right. The trouble I have is that data for these objects is stored in the database but their i sno single table for the object them selves for example I might have a Montage object that has a $User and several @Pictures the User record is stored in the database and the Picture records are also stored as individual rows in a pictures table. I want to manipulate the users along with their pictures as an object them selves, for example given a User DBIx::class objects create a method (eg get_montage) that returns a Montage. Is there a simple solution perhaps creating a DBIx::class object that doesn't actually have an underlying table but can still utilize relationships and have User::get_montage return an instance of one of these? Or am I overlooking something else that is obvious? Thanks in advance Stephen ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive:
Re: [Catalyst] Model objects from multiple DBIx::Class rows
On 22 November 2012 17:03, Stephen Shorrock stephen.shorr...@gmail.comwrote: Hi Lukas, Firstly thanks and secondly I take your point regarding the relationships. It seems sensible that I should create an object to manipulate a Montage rather than methods attached to other objects that seem to be modifying something virtual. For example a Montage might have a period associated to it so when I display the details the Montage knowing it's period can identify the pictures from it's period containing the user that belong to it and maybe on a picture rating set by the user include them to be displayed. To always have to pass start and end dates, and perhaps other Montage related attributes, to a method in the users object doesn't see right. I hate to state the obvious (honest!) but shouldn't you at this point be adding a table for the montages? Otherwise, simply creating an object as Montage-new( user = $dbicUserObject, start = ..., end = ...) doesn't seem too bad. Pass the actual user row object in and it will allow you easy enough access to the pictures in a related table (e.g. something like $user-pictures_rs-search( { date = { '=', $start, '', $startPlusPeriod } } ) for the example you gave about periods). ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] Model objects from multiple DBIx::Class rows
On Thu, Nov 22, 2012 at 5:20 PM, Will Crawford billcrawford1...@gmail.com wrote: On 22 November 2012 17:03, Stephen Shorrock stephen.shorr...@gmail.com wrote: Hi Lukas, Firstly thanks and secondly I take your point regarding the relationships. It seems sensible that I should create an object to manipulate a Montage rather than methods attached to other objects that seem to be modifying something virtual. For example a Montage might have a period associated to it so when I display the details the Montage knowing it's period can identify the pictures from it's period containing the user that belong to it and maybe on a picture rating set by the user include them to be displayed. To always have to pass start and end dates, and perhaps other Montage related attributes, to a method in the users object doesn't see right. I hate to state the obvious (honest!) but shouldn't you at this point be adding a table for the montages? Otherwise, simply creating an object as Montage-new( user = $dbicUserObject, start = ..., end = ...) doesn't seem too bad. Pass the actual user row object in and it will allow you easy enough access to the pictures in a related table (e.g. something like $user-pictures_rs-search( { date = { '=', $start, '', $startPlusPeriod } } ) for the example you gave about periods). Thanks Will, I think I'm having problems with it be just that; too obvious?! True I could create a Montages table though Montages can exists with any start end point so this would just have to be a cache. Also (perhaps I should really go away an investigate) is it possible to extend a DBIx::Class objects with extra Moose attributes? without being able to it would mean that all my attributes must be columns in the cache table. I do remember using custom result sets once so something like: __PACAKGE__-table('DUMMY4MONTAGE'); __PACKAGE__-add_columns(user={data_type=...},start={..},end={...}); result_source_instance-name($select_query ) I was perhaps hoping that relationships would then work in this user defined instance but the method didn;t seem to work well with my more recent DBIC. But like you say this seems to be going a little too far and I would have to manually set start and end anyway ( Montage-New(...)) so perhaps I'll just stick with what I have. Stephen ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/