Re: [Catalyst] Models and inflating

2009-02-23 Thread Alexander Tamm

Jonathan Rockway wrote:

functionality. If I put the functionality in the Schema::*, I will
have about 400 lines of code that I need to replicate across eight or
more sites and the classes won't be usable without DBIx::Class or
Catalyst.


No, your current solution is the one that's not usable without Catalyst
and DBIC. 


That's a weird conclusion... I admit that the example I posted was not 
very descriptive of my solution. (There were even some omissions, like 
"use Moose".) What I have done in the real applications is more 
something like:


package TestApp::Model::Foo::Bar;
use Moose;
extends 'RW::Bar';
1;

Where RW::Bar is the class with the actual functionality, completely 
independent of DBIC or any other storage solution.



If you just want some random classes, you write them:

   package Class;

  ...

   1;

I usually "wrap" the DBIC classes like this when I have operations that
logically operate on a group of "unrelated" (in the DB) objects, or
operate on two separate schemas.  (What most people do in the controller
I do in what I call "Backend" classes.  It's the glue between the
low-level DBIC stuff, and high-level operations.)


Your example does not show how Class is being used or how an object is 
created/inflated, but illustrates *basically* what I want to do.



If your classes depend on the structure of DBIC results, then the code
needs to go in your schema classes.  That is how everyone does it.
(Your "full_name" example is just the sort of thing that you would keep
inside DBIC.)


My classes don't depend on the structure. I only want to initialize 
objects with values that sometimes happen to come from a database. I was 
under the impression that this initalization can easily be done with 
DBIC, but I still haven't seen an example of a class with more complex 
functionality. I guess I could just use HashRefInflator and create my 
objects from hashrefs, but that involves a bit more repetitious code.


As I said before, the full_name example has nothing to do with my 
application. It was only for illustration.



Regards,
Alex

___
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] Models and inflating

2009-02-23 Thread Jonathan Rockway
* On Mon, Feb 23 2009, Alexander Tamm wrote:
>>> It looks a bit weird to me, but it seems to work. Should it work?
>>
>> You shouldn't do this (*), it is very confusing.  Put functions like
>> this in the row class, i.e. YourApp::Schema::Foo::User, so that all
>> users of the schema have access to these methods.
>
> The reason I want to do this (or something similar) is that I don't
> want all the database-specific cruft in the class I'm editing. I'm
> trying to keep the classes clean and separate the storage from the
> functionality. If I put the functionality in the Schema::*, I will
> have about 400 lines of code that I need to replicate across eight or
> more sites and the classes won't be usable without DBIx::Class or
> Catalyst.

No, your current solution is the one that's not usable without Catalyst
and DBIC.  If you just want some random classes, you write them:

   package Class;
   use Moose;

   has 'some_row_object' => (
   is => 'ro',
   does => 'Some::Interface',
   required => 1,
   );

   # code goes here

   1;

I usually "wrap" the DBIC classes like this when I have operations that
logically operate on a group of "unrelated" (in the DB) objects, or
operate on two separate schemas.  (What most people do in the controller
I do in what I call "Backend" classes.  It's the glue between the
low-level DBIC stuff, and high-level operations.)

If your classes depend on the structure of DBIC results, then the code
needs to go in your schema classes.  That is how everyone does it.
(Your "full_name" example is just the sort of thing that you would keep
inside DBIC.)

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"

___
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] Models and inflating

2009-02-23 Thread Alexander Tamm



It looks a bit weird to me, but it seems to work. Should it work?


You shouldn't do this (*), it is very confusing.  Put functions like
this in the row class, i.e. YourApp::Schema::Foo::User, so that all
users of the schema have access to these methods.


The reason I want to do this (or something similar) is that I don't want 
all the database-specific cruft in the class I'm editing. I'm trying to 
keep the classes clean and separate the storage from the functionality. 
If I put the functionality in the Schema::*, I will have about 400 lines 
of code that I need to replicate across eight or more sites and the 
classes won't be usable without DBIx::Class or Catalyst. I don't regard 
that as a an option. Especially, since the Schema-classes are created by 
the helper script.


If I use the method I describe, I can do this with inheritance and
keep my classes clean and available to applications that don't use 
Catalyst or DBIx::Class.



(*) BTW, the behavior you described does work intentionally, for cases
when you need the objects in Catalyst to be different than with plain
DBIC.  I think it's a bad idea to use this "feature" except in very
special cases -- of which "full_name" is not one.


full_name() was just a very simple example to illustrate the problem. 
The real use case is a lot more complex and involves functionality that 
has nothing to do with DBIx::Class.


Cheers,
Alex


___
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] Models and inflating

2009-02-23 Thread Jonathan Rockway
* On Mon, Feb 23 2009, Alexander Tamm wrote:
> Hi,
>
> I'm still a bit confused about how models using DBIx::Class should
> work in a catalyst application.
>
> Is it the case that classes placed in the Model-directory will somehow
> (magically?) let me have objects inflated as instances of the class
> using a similarly named Schema?
>
> For example, I have this class:
>
> package TestApp::Model::Foo::User;
>
> use strict;
> sub full_name {
> my ( $self ) = @_;
> return $self->first_name() . q{ } . $self->last_name();
> }
> 1;
>
> Objects created by $c->model('Foo::User') *will* work. Ie. they have
> the methods full_name(), first_name() and last_name().
>
> It looks a bit weird to me, but it seems to work. Should it work?

You shouldn't do this (*), it is very confusing.  Put functions like
this in the row class, i.e. YourApp::Schema::Foo::User, so that all
users of the schema have access to these methods.

Catalyst::Model::DBIC::Schema just proxies each class so that
$c->model('Schema::Foo') == $c->model('Schema')->resultset('Foo').
That's all you should use it for.

(*) BTW, the behavior you described does work intentionally, for cases
when you need the objects in Catalyst to be different than with plain
DBIC.  I think it's a bad idea to use this "feature" except in very
special cases -- of which "full_name" is not one.

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"

___
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/


[Catalyst] Models and inflating

2009-02-23 Thread Alexander Tamm

Hi,

I'm still a bit confused about how models using DBIx::Class should work 
in a catalyst application.


Is it the case that classes placed in the Model-directory will somehow 
(magically?) let me have objects inflated as instances of the class 
using a similarly named Schema?


For example, I have this class:

package TestApp::Model::Foo::User;

use strict;
sub full_name {
my ( $self ) = @_;
return $self->first_name() . q{ } . $self->last_name();
}
1;

Objects created by $c->model('Foo::User') *will* work. Ie. they have the 
methods full_name(), first_name() and last_name().


It looks a bit weird to me, but it seems to work. Should it work?

I also have another application A which has a more complex setup. 
Application A also works. OTOH, application B, which is very similar to 
application A, does *not* work. I get an error message saying "Can't 
locate object method "inflate_result" via package B::Model::DB::Snafu.


Can't really paste the code here, but I'd like some pointers where to 
look for the cause of the error. Should it work at all, or do TestApp 
and A work through some weird lucky bug?


Cheers,
Alex


___
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/