Adding row

View: New views
10 Messages — Rating Filter:   Alert me  

Adding row

by Michał Zieliński :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

ad.1.
how should I add new row to db? Is there any preferable method?
Should I use:
- SQL in $db->query() method
- $model->insert() method
- maybe I should createRow() and then save() using Zend_Db_Table_Row?

ad.2.
How about tables which have references to other tables? While updating one row in table X I have to check selected row in table Y. If row in Y doesn`t exist it is added and its new id must be saved in dependent table X. Where should I make this decision if I must add new row to different table (depenedent)? In controller or model for table X?

Could you please give me advice in these cases?
Thanks in advance.

Re: Adding row

by David Mintz-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Wed, Jul 2, 2008 at 4:36 AM, Michał Zieliński <zielun@...> wrote:

ad.1.
how should I add new row to db? Is there any preferable method?
Should I use:
- SQL in $db->query() method
- $model->insert() method
- maybe I should createRow() and then save() using Zend_Db_Table_Row?

ad.2.
How about tables which have references to other tables? While updating one
row in table X I have to check selected row in table Y. If row in Y doesn`t
exist it is added and its new id must be saved in dependent table X. Where
should I make this decision if I must add new row to different table
(depenedent)? In controller or model for table X?


re question 1, where $table is a descendant of Zend_Db_Table_Abstract and $data is an associative array of filtered and validated data, I am fond of

$table->createRow($data)->save();

re question 2 I defer to the experts. But... I think you can make a case for putting some of that logic in the controller, and still keep your controller pretty thin. controller decides what methods to call on model.

--
David Mintz
http://davidmintz.org/

The subtle source is clear and bright
The tributary streams flow through the darkness

Re: Adding row

by Bill Karwin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


David Mintz-3 wrote:
> ...exist it is added and its new id must be saved in dependent table X. Where
> should I make this decision if I must add new row to different table
> (depenedent)? In controller or model for table X?

re question 2 I defer to the experts. But... I think you can make a case for
putting some of that logic in the controller, and still keep your controller
pretty thin. controller decides what methods to call on model.
This is "Rails" thinking, which is poor OO design.  The relationship between Models and Tables is "has-a" instead of "is-a".

Your Model class should encapsulate business logic, even if that business logic needs to be backed by multiple tables.  Think of this as an opportunity to increase cohesion in a good way in your application.

Writing code in the Controller class to manage data integrity across multiple tables is not good.  Your Controller should just invoke a Model and tell it, "do what you need to do to save this data."  The Model should know how the data is structured in the database; no other class should need to know that.  That way, if the structure of the database changes, but your Model's interface remains the same, you update the code in the Model and the change is transparent to Controllers and Views who use that Model.

Regards,
Bill Karwin

Re: Adding row

by David Mintz-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Wed, Jul 2, 2008 at 2:33 PM, Bill Karwin <bill@...> wrote:



David Mintz-3 wrote:
>
>> ...exist it is added and its new id must be saved in dependent table X.
>> Where
>> should I make this decision if I must add new row to different table
>> (depenedent)? In controller or model for table X?
>
> re question 2 I defer to the experts. But... I think you can make a case
> for
> putting some of that logic in the controller, and still keep your
> controller
> pretty thin. controller decides what methods to call on model.
>

This is "Rails" thinking, which is poor OO design.  The relationship between
Models and Tables is "has-a" instead of "is-a".

Your Model class should encapsulate business logic, even if that business
logic needs to be backed by multiple tables.  Think of this as an
opportunity to increase cohesion in a good way in your application.

Writing code in the Controller class to manage data integrity across
multiple tables is not good.  Your Controller should just invoke a Model and
tell it, "do what you need to do to save this data."  The Model should know
how the data is structured in the database; no other class should need to
know that.  That way, if the structure of the database changes, but your
Model's interface remains the same, you update the code in the Model and the
change is transparent to Controllers and Views who use that Model.


OK, and if a Model happens to need to instantiate other Models to do its thing, so be it. Makes sense. Thanks.

--
David Mintz
http://davidmintz.org/

The subtle source is clear and bright
The tributary streams flow through the darkness

Re: Adding row

by Bill Karwin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


David Mintz-3 wrote:
OK, and if a Model happens to need to instantiate other Models to do its
thing, so be it. Makes sense. Thanks.
It's true that a Model can instantiate another Model.

But I'm guessing that you might still think a Model and a Table are the same class.  This is not true in general.

Rails popularized use of the term "Model" as equivalent to "ActiveRecord" but this is an oversimplification, part of the Rails "opinionated software" culture.  It's not generally correct in an MVC architecture.

For more on this subject, see my blog from May:
http://karwin.blogspot.com/2008/05/activerecord-does-not-suck.html

Regards,
Bill Karwin

Re: Adding row

by David Mintz-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Wed, Jul 2, 2008 at 7:05 PM, Bill Karwin <bill@...> wrote:
David Mintz-3 wrote:
>
> OK, and if a Model happens to need to instantiate other Models to do its
> thing, so be it. Makes sense. Thanks.
>

It's true that a Model can instantiate another Model.

But I'm guessing that you might still think a Model and a Table are the same
class.  This is not true in general.

Rails popularized use of the term "Model" as equivalent to "ActiveRecord"
but this is an oversimplification, part of the Rails "opinionated software"
culture.  It's not generally correct in an MVC architecture.

For more on this subject, see my blog from May:
http://karwin.blogspot.com/2008/05/activerecord-does-not-suck.html


Very interesting, Bill. Thanks again.

I think the one-model-per-table notion is partly encouraged by the notion of "data model" itself. The customer data table _models_ a living breathing customer. Another thing is the examples in the Zend_Db doc can be (mis-)construed as suggesting  "MyModel extends Zend_Db_Table_Abstract."

But this lesson is inspiring me to reconsider my approach to a little project I have just started.  I think I might just have a person-type model extend nothing and *have a* couple of descendants of Zend_Db_Table_Abstract as instance vars.



--
David Mintz
http://davidmintz.org/

The subtle source is clear and bright
The tributary streams flow through the darkness

Re: Adding row

by Bill Karwin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Mintz-3 wrote:
Very interesting, Bill. Thanks again.

I think the one-model-per-table notion is partly encouraged by the notion of
"data model" itself. The customer data table _models_ a living breathing
customer. Another thing is the examples in the Zend_Db doc can be
(mis-)construed as suggesting  "MyModel extends Zend_Db_Table_Abstract."
Really?  I just grepped the manual source and I can't find any occurrence of the word 'MyModel' anywhere.  Can you find where you saw that?

Anyway, I think of the Model as a "Domain Model" instead of "Data Model."  Martin Fowler gives a brief definition of Domain Model as "an object model of the domain that incorporates both behavior and data."

The behavior of a domain model is _not_ create, read, update, delete.  The behavior of a domain model is higher-level, like "add a player to this sports team".   There's no reason why a Domain Model class should expose CRUD operations to the caller, it just makes it too easy for improper code to make invalid changes in your database.

David Mintz-3 wrote:
But this lesson is inspiring me to reconsider my approach to a little
project I have just started.  I think I might just have a person-type model
extend nothing and *have a* couple of descendants of Zend_Db_Table_Abstract
as instance vars.
Yes, that's what I would do.

There may be cases where it's sufficient to make your Model extend a Table directly.  But aside from trivial cases like populating a drop-down list in a form, I think it's better to design a Model class in the way you describe, extending no base class.  Inside the Model, it may instantiate one or more Table classes or it may just write SQL queries directly, skipping the Table gateway.

Regards,
Bill Karwin

Re: Adding row

by Michał Zieliński :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks guys.
I used to think about model as Bill described (domain model). I`m glad that this is how it should be done. Thanks Bill for clarifications.

I used to create small CRUD methods in models and if one model needs to get more data from other table (model) it uses these simple methods i.e.
People table contains references to city table. So to get all data about Person i have to use city table to get person`s city name. So in the People->getPerson($id) I use city model $City->getNameById($idCity);
Controller just has to decide what data it needs and not how to receives it from db tables and which ones. This is a model job.



Bill Karwin wrote:
David Mintz-3 wrote:
Very interesting, Bill. Thanks again.

I think the one-model-per-table notion is partly encouraged by the notion of
"data model" itself. The customer data table _models_ a living breathing
customer. Another thing is the examples in the Zend_Db doc can be
(mis-)construed as suggesting  "MyModel extends Zend_Db_Table_Abstract."
Really?  I just grepped the manual source and I can't find any occurrence of the word 'MyModel' anywhere.  Can you find where you saw that?

Anyway, I think of the Model as a "Domain Model" instead of "Data Model."  Martin Fowler gives a brief definition of Domain Model as "an object model of the domain that incorporates both behavior and data."

The behavior of a domain model is _not_ create, read, update, delete.  The behavior of a domain model is higher-level, like "add a player to this sports team".   There's no reason why a Domain Model class should expose CRUD operations to the caller, it just makes it too easy for improper code to make invalid changes in your database.

David Mintz-3 wrote:
But this lesson is inspiring me to reconsider my approach to a little
project I have just started.  I think I might just have a person-type model
extend nothing and *have a* couple of descendants of Zend_Db_Table_Abstract
as instance vars.
Yes, that's what I would do.

There may be cases where it's sufficient to make your Model extend a Table directly.  But aside from trivial cases like populating a drop-down list in a form, I think it's better to design a Model class in the way you describe, extending no base class.  Inside the Model, it may instantiate one or more Table classes or it may just write SQL queries directly, skipping the Table gateway.

Regards,
Bill Karwin

Re: Adding row

by David Mintz-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Thu, Jul 3, 2008 at 2:22 PM, Bill Karwin <bill@...> wrote:


David Mintz-3 wrote:
>
> Very interesting, Bill. Thanks again.
>
> I think the one-model-per-table notion is partly encouraged by the notion
> of
> "data model" itself. The customer data table _models_ a living breathing
> customer. Another thing is the examples in the Zend_Db doc can be
> (mis-)construed as suggesting  "MyModel extends Zend_Db_Table_Abstract."
>

Really?  I just grepped the manual source and I can't find any occurrence of
the word 'MyModel' anywhere.  Can you find where you saw that?


Ouch! Bill, my apologies for my lack of clarity. I ought to have said, there are examples e.g., "class Bugs extends Zend_Db_Table_Abstract" which might lead a reader to think....
 

<snip/>


David Mintz-3 wrote:
>
> But this lesson is inspiring me to reconsider my approach to a little
> project I have just started.  I think I might just have a person-type
> model extend nothing and *have a* couple of descendants of
> Zend_Db_Table_Abstract as instance vars.
>

Yes, that's what I would do.

There may be cases where it's sufficient to make your Model extend a Table
directly.  But aside from trivial cases like populating a drop-down list in
a form, I think it's better to design a Model class in the way you describe,
extending no base class.  Inside the Model, it may instantiate one or more
Table classes or it may just write SQL queries directly, skipping the Table
gateway.



Which brings up another point that this perpetual newb often thinks about:  it is not a crime to write some SQL. Sometimes I feel like something's is wrong if I fail to leverage the high-level CRUD methods provided by Zend_Db_Xxx

--
David Mintz
http://davidmintz.org/

The subtle source is clear and bright
The tributary streams flow through the darkness

Re: Adding row

by Bill Karwin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


David Mintz-3 wrote:
I ought to have said, there
are examples e.g., "class Bugs extends Zend_Db_Table_Abstract" which might
lead a reader to think....
Yeah, fair enough.  It's appropriate in the chapter on Zend_Db_Table, to show how to declare and use the table class.  And since there is no actual chapter on "Zend_Model", one is left to the assumption that bare Table classes should be used _as_ the Model.

Someone on my blog suggested that there should be a chapter in the ZF manual titled "Zend_Model" even though there is no component by that name.  The chapter would clarify what a Model is, and show examples of designing and using Models, which in turn may utilize Table classes.  I think this idea is a good one.

David Mintz-3 wrote:
...it is not a crime to write some SQL. Sometimes I feel like something's is
wrong if I fail to leverage the high-level CRUD methods provided by
Zend_Db_Xxx
Yes, I have watched the extraordinary lengths to which many people want to go, to surface every conceivable database operation through the Table interface.  I really don't see the need for that, when there are easy methods to execute SQL directly.  

But it seems software developers hate SQL so passionately that they'd rather implement new classes to do the equivalent operations, and they don't care that writing an SDK with that amount of functionality  would take about 100 engineer-years of work.

Regards,
Bill Karwin
LightInTheBox - Buy quality products at wholesale price