DBIx/Bio::Chado::Schema subclassing

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

DBIx/Bio::Chado::Schema subclassing

Bob MacCallum
Hi guys (Naama and Rob at least!),

I'm subclassing nd_experiment and do the following (see below) cunning
bit of DBIx magic to ensure that
  $schema->resultset('Experiment::FieldCollection')->all
gets me only the records of the appropriate sub-type.

package Bio::Chado::NatDiv::API::Result::Experiment::FieldCollection;
use base 'Bio::Chado::NatDiv::API::Result::Experiment'; # which in
turn subclasses
Bio::Chado::Schema::Result::NaturalDiversity::NdExperiment
#
# I do some other magic here to make sure relationships are
re-established between my subclasses and
# not the BCS classes - but they are not relevant for this question.
The next line is what we're talking about:
#
__PACKAGE__->resultset_attributes({ join => 'type', where => {
'type.name' => 'field collection' } });


That's all good and well, but I was hoping to remove multiple copies
of hardcoded text ("field collection") in my code and would rather do
something like

__PACKAGE__->resultset_attributes({ where => { 'type_id' =>
$field_collection_type->cvterm_id } });

where $field_collection_type comes from a $schema object and the data
comes from the database (via some convenience/util class method which
is the only place the "field collection" text is present).  The
trouble is, at class load time - there is no $schema object so I can't
do it like this (of course).

I explored trying to do the resultset_attributes() in an overloaded
constructor for the resultset (when a resultset instance is created,
it should already have a result source and schema), but that didn't
work, but TBH I can't be sure I was doing it right.

I'll ask on the dbic IRC channel if you guys have no suggestions, but
asking here saved me re-phrasing the problem more generally.

Thanks very much,
cheers,
Bob.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Gmod-schema mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gmod-schema
Reply | Threaded
Open this post in threaded view
|

Re: DBIx/Bio::Chado::Schema subclassing

Bob MacCallum
OP here...  I managed to get it to work - and it doesn't break any of
my existing tests :-)

For anyone who's interested I removed the
__PACKAGE__->resultset_attributes(...) from the result class and
adding the following constructor wrapper to the resultset subclass:


package Bio::Chado::NatDiv::API::ResultSet::Experiment::FieldCollection;

use base 'Bio::Chado::NatDiv::API::ResultSet::Experiment';
use Carp;
use strict;

sub new {
  my ($class, $source, $attribs) = @_;
  if (keys %{$attribs} == 0) {
    my $type = $source->schema->types->field_collection;  # types()
returns a utility/factory object for cvterms
    $attribs = { where => { 'type_id' => $type->cvterm_id } };
  }
  return $class->SUPER::new($source, $attribs);
}


It makes me feel a bit uneasy hacking new() like this (one is supposed
to do specialised initialisation in a non-constructor) but I couldn't
see any alternatives.

cheers,
Bob.


On Sun, May 20, 2012 at 10:00 PM, Bob MacCallum
<[hidden email]> wrote:

> Hi guys (Naama and Rob at least!),
>
> I'm subclassing nd_experiment and do the following (see below) cunning
> bit of DBIx magic to ensure that
>  $schema->resultset('Experiment::FieldCollection')->all
> gets me only the records of the appropriate sub-type.
>
> package Bio::Chado::NatDiv::API::Result::Experiment::FieldCollection;
> use base 'Bio::Chado::NatDiv::API::Result::Experiment'; # which in
> turn subclasses
> Bio::Chado::Schema::Result::NaturalDiversity::NdExperiment
> #
> # I do some other magic here to make sure relationships are
> re-established between my subclasses and
> # not the BCS classes - but they are not relevant for this question.
> The next line is what we're talking about:
> #
> __PACKAGE__->resultset_attributes({ join => 'type', where => {
> 'type.name' => 'field collection' } });
>
>
> That's all good and well, but I was hoping to remove multiple copies
> of hardcoded text ("field collection") in my code and would rather do
> something like
>
> __PACKAGE__->resultset_attributes({ where => { 'type_id' =>
> $field_collection_type->cvterm_id } });
>
> where $field_collection_type comes from a $schema object and the data
> comes from the database (via some convenience/util class method which
> is the only place the "field collection" text is present).  The
> trouble is, at class load time - there is no $schema object so I can't
> do it like this (of course).
>
> I explored trying to do the resultset_attributes() in an overloaded
> constructor for the resultset (when a resultset instance is created,
> it should already have a result source and schema), but that didn't
> work, but TBH I can't be sure I was doing it right.
>
> I'll ask on the dbic IRC channel if you guys have no suggestions, but
> asking here saved me re-phrasing the problem more generally.
>
> Thanks very much,
> cheers,
> Bob.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Gmod-schema mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gmod-schema
Reply | Threaded
Open this post in threaded view
|

Re: DBIx/Bio::Chado::Schema subclassing

Naama Menda
hi Bob,
glad you found a solution. 
This seems to me more a Perl subcalssing issue than a DBIx Class problem.
Maybe Rob will have some insight?

-Naama



On Mon, May 21, 2012 at 7:27 AM, Bob MacCallum <[hidden email]> wrote:
OP here...  I managed to get it to work - and it doesn't break any of
my existing tests :-)

For anyone who's interested I removed the
__PACKAGE__->resultset_attributes(...) from the result class and
adding the following constructor wrapper to the resultset subclass:


package Bio::Chado::NatDiv::API::ResultSet::Experiment::FieldCollection;

use base 'Bio::Chado::NatDiv::API::ResultSet::Experiment';
use Carp;
use strict;

sub new {
 my ($class, $source, $attribs) = @_;
 if (keys %{$attribs} == 0) {
   my $type = $source->schema->types->field_collection;  # types()
returns a utility/factory object for cvterms
   $attribs = { where => { 'type_id' => $type->cvterm_id } };
 }
 return $class->SUPER::new($source, $attribs);
}


It makes me feel a bit uneasy hacking new() like this (one is supposed
to do specialised initialisation in a non-constructor) but I couldn't
see any alternatives.

cheers,
Bob.


On Sun, May 20, 2012 at 10:00 PM, Bob MacCallum
<[hidden email]> wrote:
> Hi guys (Naama and Rob at least!),
>
> I'm subclassing nd_experiment and do the following (see below) cunning
> bit of DBIx magic to ensure that
>  $schema->resultset('Experiment::FieldCollection')->all
> gets me only the records of the appropriate sub-type.
>
> package Bio::Chado::NatDiv::API::Result::Experiment::FieldCollection;
> use base 'Bio::Chado::NatDiv::API::Result::Experiment'; # which in
> turn subclasses
> Bio::Chado::Schema::Result::NaturalDiversity::NdExperiment
> #
> # I do some other magic here to make sure relationships are
> re-established between my subclasses and
> # not the BCS classes - but they are not relevant for this question.
> The next line is what we're talking about:
> #
> __PACKAGE__->resultset_attributes({ join => 'type', where => {
> 'type.name' => 'field collection' } });
>
>
> That's all good and well, but I was hoping to remove multiple copies
> of hardcoded text ("field collection") in my code and would rather do
> something like
>
> __PACKAGE__->resultset_attributes({ where => { 'type_id' =>
> $field_collection_type->cvterm_id } });
>
> where $field_collection_type comes from a $schema object and the data
> comes from the database (via some convenience/util class method which
> is the only place the "field collection" text is present).  The
> trouble is, at class load time - there is no $schema object so I can't
> do it like this (of course).
>
> I explored trying to do the resultset_attributes() in an overloaded
> constructor for the resultset (when a resultset instance is created,
> it should already have a result source and schema), but that didn't
> work, but TBH I can't be sure I was doing it right.
>
> I'll ask on the dbic IRC channel if you guys have no suggestions, but
> asking here saved me re-phrasing the problem more generally.
>
> Thanks very much,
> cheers,
> Bob.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Gmod-schema mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gmod-schema


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Gmod-schema mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gmod-schema