[Catalyst] Instant CRUD with DBIC::Schema

Zbigniew Lukasiak zzbbyy at gmail.com
Wed Mar 12 14:29:29 GMT 2008


On Wed, Mar 12, 2008 at 2:55 PM, Peter Karman <peter at peknet.com> wrote:
>
>
>  On 03/12/2008 05:50 AM, Zbigniew Lukasiak wrote:
>  > After some more playing with CatalystX::CRUD I think I can formulate
>  > my arguments a bit more clearly.
>  >
>  > I believe the objects that users of CatalystX::CRUD get in their
>  > controller should be the real things - i.e. objects from their models
>  > not CatalystX::CRUD::Model::Objects.  This would be the  minimal
>  > interface and minimal hassle for injecting CatalystX::CRUD::Controller
>  > actions to a legacy Catalyst controller.
>  >
>
>  Let me outline the problem I was trying to solve, and maybe you can suggest an alternate
>  solution. Or explain why the problem I see is not the problem you see.
>
>  My original idea for CX::CRUD was to design an API that was high-level enough that a CRUD
>  Controller would not need to know anything specific about a CRUD Model, except what was
>  defined by the CX::CRUD API. That is, if I was using Rose::HTML::Objects to manage my
>  forms, my Controller could exchange DBIC for RDBO as its Model and not need to change any
>  Controller code. Likewise, the Model need not know anything about the Controller except
>  what was defined by the API. Ideally, all the logic for Controller and Model is
>  encapsulated within each, and they talk to each other minimally and only through
>  well-defined methods.
>
>  Some levels of indirection were thus required. CX::CRUD is duct tape, but it ought to be
>  sensible and predictable how the duct tape works.
>
>  So then the questions began. Assuming I have a $form and an $object:
>
>  (1) where and how should they interact? Should they interact in the Controller or the
>  Model? Or somewhere not either of those?
>
>  (2) should the $form and $object have any expectations about the methods available on the
>  other object? Or how else can they interact in a relatively agnostic way?
>
>  >From a programming philosophy perspective, I could be persuaded about the answer to (1). I
>  don't have strong opinions. IME, it's more practical for me in my Cat apps to put workflow
>  kinds of code in a Controller, make my Models as thin as possible, and put as much code as
>  possible in classes outside of Catalyst altogether. For CX::CRUD, I compromised, based on
>  the pattern I followed in Catalyst::Controller::CRUD, and put the basic $form/$object
>  interaction in the Controller, and made the Model a thin/convenient wrapper around the
>  non-Catalyst model class(es). I did this because, to my way of thinking, it makes a
>  sensible parallel construction to implement Form processing in the Controller and storage
>  processing (business logic, whatever you want to call it) in the Model. The Model knows
>  nothing about Forms; the Form is just one way of getting data to and from the Model, and
>  since facilitating workflow is what a Controller does, the Form belongs in the Controller.
>

See my other email - you don't need to force the user to change their
models to fit into your controllers - your controller code can do the
wrapping itself.  And since the programmers are usually more familiar
with the original ORM package than with your wrappers you should let
them work with the original objects and only use the wrapped ones in
your code.

Once again - think about the minimal interface for the user, the
minimal learning  - this is the what is convenient for the users of
the library.


>  Since I decided to put the $form/$object code in the Controller, the answer to (2) became
>  more obvious to me: the objects should have some common expectations about each other. In
>  the case of the $object, the $form should expect the $object to implement the basic CRUD
>  methods: create() read() update() delete(). That's where CatalystX::CRUD::Object came
>  from. It abstracts those 4 methods and leaves it up to CX::CRUD::Model authors to
>  implement them for their particular model package (ORM, whatever).
>
>  In the case of the $form, the $object should expect some way of getting and setting data
>  (moving data to/from) the $form. That's where the CX::CRUD::Controller config values for
>  'init_form' and 'init_object' come from, and why the form_to_object() method is not
>  implemented in the base Controller but left up to the specific Form implementation (like
>  in CX::CRUD::Controller::RHTMLO).
>
>  Now granted, a lot of my API ideas are influenced by how RHTMLO and RDBO work. I don't
>  apologize for that; I like those APIs, which is why I use those packages.
>
>  But I can understand that the DBIC/FormFu folks think differently, which is why there is
>  more than one ORM and Form package out there. :)
>
>  So, assuming I have identified the design problems correctly, I can imagine an alternate
>  solution. Get rid of CatalystX::CRUD::Object. Put the create/read/update/delete methods in
>  CatalystX::CRUD::Model instead. Change the base Controller behaviour to do this:
>
>   $c->model( $self->model_name )->create( $object );
>
>  instead of this (what it does currently):
>
>   $object->create;
>
>  Now, I like the current implementation because it is (a) terser and (b) seems clearer to
>  me what is happening.
>
>  But if the design goal of common expectations for $form and $object is to be achieved, we
>  need some way of defining that API. I'm open to suggestions of how to get rid of
>  CX::CRUD::Object and still defining a way for Controllers to be Model agnostic.
>
>  --
>
>
> Peter Karman  .  peter at peknet.com  .  http://peknet.com/
>
>
>  _______________________________________________
>  List: Catalyst at 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/
>



-- 
Zbigniew Lukasiak
http://brudnopis.blogspot.com/



More information about the Catalyst mailing list