[Dbix-class] RE: Inheritance question..
Oleg Pronin
syber.rus at gmail.com
Thu Jan 22 01:39:38 GMT 2009
1) DBIx::Class::DynamicSubclass will automaticaly subclass your row object
when
a) fetched from DB
b) created (->new or ->create)
c) changed subclassing column
For example when type =3D null row is BaseClass, when type =3D 1 r=
ow is
ClassA, when 2 row is ClassB.
my $row =3D $rs->new({type =3D> 1}); # $row is ClassA
$row->type(2); #$row is ClassB
$row->type(undef); #$row is BaseClass
2) You can set up dynamic columns with subclassing if you use
DBIx::Class::DynamicSubclass + DBIx::Class::FrozenColumns. But there is
caveat: you will not be able to use 'frozen' columns in WHERE clause in SQL.
The idea is:
package BaseClass;
->load_components(qw/DynamicSubclass FrozenColumns Core/);
->add_columns(qw/all_columns_that_are_common_to_all_subclasses + type
+ data/);
#data must be of type blob or text (depends on storage engine)
->typecast_map(type =3D> {1 =3D> 'ClassA', 2 =3D> 'ClassB'});
package ClassA;
use parent 'BaseClass';
->add_frozen|dumped|json_columns(data =3D>
qw/all_columns_that_are_specific_to_ClassA for_example/);
package MyCode;
my $row =3D $rs->create({type =3D> 1});
$row->for_example('hello'); #ok
$row->type(2);
$row->for_example('hello'); # error
$rs->new({ type=3D> 1, for_example =3D> 'hello' }); #that's ok too
This is not ideal mechanism, but it quite useful and it helps me many times.
2009/1/21 Howe, Tom (IDEAS PRACTICE AREAS) <Tom.Howe at morganstanley.com>
> Further to my question on inheritance, I have been trying subclassing and
> the proxy method options and have a couple of other questions.
>
>
> First, in an attempt to try the single flattened style where all Foo obje=
ct
> reside in one table, I tried the cookbook entry on "Dynamic Sub-classing
> DBIx::Class proxy classes".
>
> I set up a db table called foo, created a Foo class with an
> inflate_result() method and a Foo::Noisy class that inherited from the Foo
> class.
>
> I can now create the Foo object and have it inflate into a Foo::Noisy
> class.
>
> But, I cant get a Foo::Noisy resultset.
>
> I thought maybe I could define Foo with only the common columns, then
> create a Foo::Noisy subclass that would inherit the columns of Foo and th=
en
> I could create a default value for 'type' and use add_columns() to define
> the additional NoisyFoo column 'decibels'.
>
> But it seems the only resultset I can get is for Foo. So anyone creating
> objects could inadvertently set a 'colour' for a NoisyFoo or a 'decibel' =
for
> ColouredFoo.
>
>
>
>
>
> The second thing I tried was to create 3 separate tables for Foo, NoisyFoo
> and ColouredFoo. Then I created a Foo::Noisy class with a has_one
> relationship to the Foo class using a proxy=3D>[] defined to allow transp=
arent
> setting/getting of the 'name'.
>
> This works to a degree in that I can do :
>
> my $nf =3D $schema->resultset('Foo::Noisy')->create({id=3D>1, decibels=3D=
>110});
> $nf->name('mynoisyfoo');
>
> But it fails if I try to do:
> my $nf =3D $schema->resultset('Foo::Noisy')->create({id=3D>1, decibels=3D=
>110,
> name=3D>'noisyfoo'});
>
> Giving the error:
> DBIx::Class::ResultSet::create(): No such column name on DB::Foo::Noisy
>
> The proxy doesn't seem to be in affect during creation.
>
> Also, if I *don't* set the name, I don't get a row in the Foo table.
> Is there a way to enforce that the row is created?
>
> Otherwise, if I want to search for all Foos, I cant do it on the common
> table.
>
> Is there anyway to ensure the Foo row is created and grn can be passed on
> create?
>
>
>
>
>
> > -----Original Message-----
> > From: Howe, Tom (IDEAS PRACTICE AREAS)
> > Sent: 21 January 2009 09:42
> > To: DBIx::Class user and developer list
> > Subject: [Dbix-class] Inheritance question..
> >
> > Class structure is something like this..
> >
>
> +------+ +------------+ +-------------+
> | Bar |---o| Relation |o - - - - - - | Foo |abstract
> +------+ +------------+ +-------------+class
> | id | | attrs |o | id |
> | name | +------------+ \_________ | name |
> +------+ \ \ +-------------+
> \ \___^_____ ^
> \ | \ |
> \ +------------+ +-------------+
> \| NoisyFoo | | ColouredFoo |
> +------------+ +-------------+
> | id | | id |
> | decibels | | color |
> +------------+ +-------------+
>
> > +-------------+
> >
> > Bar has many Relations
> > NoisyFoo has many Relations
> > ColouredFoo has many Relations
> > Bar many-many NoisyFoos
> > Bar many-many ColouredFoos
> >
> > (Bar many-many Foos?)
> >
> >
> > NoisyFoo and ColouredFoo inherit from Foo
> >
> > It actually gets more complicated than this because
> > - Bar and Foo both inherit from a base object.
> > - All objects have a unique id are connected via Relation objects
> > - The relation object also contains levels of inheritance
> >
> > I want to be able to do queries like
> >
> > 1) Given a Bar, find all related Foo objs
> > 2) Given a NoisyFoo or Coloured Foo, find all related Bars
> > 3) For all bars with name matching "%str%" find all NoisyFoos
> > with decibels > '100'
> >
> > Im not sure whether it would be better to
> > a) retain Foo, NoisyFoo and ColouredFoo as a 3 separate tables,
> > b) flatten to 2 tables, so NoisyFoo and ColouredFoo get their
> > own name column
> > c) flatten all Foos to 1 Foo table and create a Type column
> > to differentiate.
> >
> >
> > Questions:
> >
> > Is it possible to create Foo, NoisyFoo and ColouredFoo as
> > separate tables (a), then create corresponding DBIx proxy
> > classes for them in such a way that when I create a new
> > NoisyFoo row, the 'name' value is automatically entered into
> > the Foo table? And when I retrieve the row it is
> > automatically read in from the Foo table?
> >
> >
> > If I were to flatten to 1 table per subclass (b), how would I
> > write a relationship that enabled me to perform query (1)
> > above; find all Foos for a given Bar.
> > --------------------------------------------------------
> >
> > NOTICE: If received in error, please destroy and notify
> > sender. Sender does not intend to waive confidentiality or
> > privilege. Use of this email is prohibited when received in error.
> >
> > _______________________________________________
> > List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> > IRC: irc.perl.org#dbix-class
> > SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> > Searchable Archive:
> > http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk
> >
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender. Sender do=
es
> not intend to waive confidentiality or privilege. Use of this email is
> prohibited when received in error.
>
> _______________________________________________
> List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> IRC: irc.perl.org#dbix-class
> SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> Searchable Archive:
> http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/dbix-class/attachments/20090122/d6a=
f5d88/attachment-0001.htm
More information about the DBIx-Class
mailing list