RowObjectBehavior Row Data Gateway implementation

By Anton (freenity)
"A Row Data Gateway gives you objects that look exactly like the record in your record structure but can be accessed with the regular mechanisms of your programming language. All details of data source access are hidden behind this interface." - Martin Fowler (http://www.martinfowler.com/eaaCatalog/rowDataGateway.html)
Download: http://freenity.googlecode.com/files/RowObjectBehavior%20v.%200.2.rar
Note: The version 0.2 was release, please update.

Model represents a table, it's a container which puts all the data retrieval logic inside it. The row level, that is a single record in this model should contain row level access logic. Currently we can obtain an array representing the row. We can only get data, what in most cases is fine, but it violates OOP principles by separating operations from data. One of the very useful design pattern we could implement is Row Data Gateway, that is represent a row as an object.

RowObjectBehavior does exactly this. By allowing you create objects that will represent your rows. It uses the afterFind() method to convert the array results into an object and adds some CRUD methods.

By just including the behavior you will get two functions that will operate on this record level: save() and remove()

Model Class:

Download code <?php 
class TestModel extends AppModel {
    var 
$actsAs = array('RowObject' => array('rowClass' => 'TestRow'));
}
?>

By setting rowClass we could set our own row class which has to be created in models/ directory. This class should extends from AppRow class. If nothing is specified in the rowClass option, AppRow is used.

AppRow works just like AppModel or AppController, it contains all the methods shared among all the row classes. This is an optional class, and it can be created in the app folder as app_row.php AppRow class must extend Row.

Some examples:
Download code
public function showSomeFeatures() {
    $user = $this->findById(2);
    $user->name = 'Another name';
    $user->save();
    $user->remove();
}

More examples are available at http://code.google.com/p/freenity/wiki/RowObjectBehavior
NOTE: most of the time you can work with models without using this, as the model will do it's job just fine, but there are some use cases where having this kind of abstraction is really useful specially for application maintaining.

Page 2: Code

Comments 895

CakePHP Team Comments Author Comments
 

Comment

1 Very neat for a 0.1 release

I love the idea and this is a great start. Thanks for being willing to share your 0.1 release with the world!
Posted Dec 29, 2008 by Daniel Farrell
 

Comment

2 Some FYI's

I'm playing around with this some today. Just some FYI's for others who want to play with it:

1. I had to override the model _findCount and _findList functions in my app_model
2. I had to override the helper value function in my app_helper
3. Associated objects(has many, etc) do not get the associated type yet. They are just normal objects.

I very much like the feel of this though. It seems to me to be what CakePHP2 will be like.

Posted Dec 30, 2008 by Daniel Farrell
 

Comment

3 Re: Some FYI's

Hi, I'm glad you are interested in this behavior.

Thanks for that, what problems do you get with the helper? Btw, I've updated to the 0.2 version today, and added toArray() method, that could be helpful to send data to the helpers, or other models.

About the associations. For associated models to be converted into objects as well, they have to use the behavior too.
If they don't use it, you will get only one object and associated models will be arrays.
Posted Dec 30, 2008 by Anton