| Under Construction This proposal is under construction and is not ready for review. |
Zend Framework: Zend_Db_ActiveRecord Component Proposal
| Proposed Component Name | Zend_Db_ActiveRecord |
|---|---|
| Developer Notes | http://framework.zend.com/wiki/display/ZFDEV/Zend_Db_ActiveRecord |
| Proposers | Ken Chau |
| Revision | 1.0 - 03/05/2008: Initial draft (wiki revision: 24) |
Table of Contents
1. Overview
Zend_Db_ActiveRecord is an implementation of the ActiveRecord pattern based on the Patterns of Enterprise Application Architecture book by Martin Fowler. It also has similar functionality as the Ruby on Rails ActiveRecord implementation. This implementation relies on PHP 5.3's late static binding capability (currently not in stable yet).
2. References
- Martin Fowler's Patterns of Enterprise Application Architecture Book (PoEAA)
- Ruby on Rails implementation
- What's new in PHP 5.3?
3. Component Requirements, Constraints, and Acceptance Criteria
An implementation of ActiveRecord according to PoEAA (Fowler, 161) should have the following characteristics:
- Construct an instance of the Active Record from a SQL result set row
- Construct a new instance for later insertion into table
- Static finder methods to wrap commonly used SQL queries and return Active Record objects
- Update the database and insert into it the data in the Active Record
- Get and set the fields
- Implement some pieces of business logic
In the Zend Framework context, here are the requirements:
- This component will perform CRUD operations on a table mapped to an ActiveRecord object.
- This component will use existing Zend_Db for all actual database operations.
- This component will use static find methods and treat instantiations to be an object representation of a table row.
- This component will allow for global default configuration much like Zend_Db_Table_Abstract.
- This component will work with validators and filters as "some pieces of business logic"
4. Dependencies on Other Framework Components
- Zend_Exception
- Zend_Db
- Zend_Db_Select
5. Theory of Operation
6. Milestones / Tasks
- Milestone 1: design notes will be published here
- Milestone 2: Working prototype checked into the incubator supporting use cases #1, #2, ...
- Milestone 3: Working prototype checked into the incubator supporting use cases #3 and #4.
- Milestone 4: Unit tests exist, work, and are checked into SVN.
- Milestone 5: Initial documentation exists.
7. Class Index
- Zend_Db_ActiveRecord_Abstract
8. Use Cases
| UC-01 |
|---|
Declaring an ActiveRecord Model, defining Relationships
| UC-02 |
|---|
Create, Update, Delete
| UC-03 |
|---|
Find a record in the table by ID and by where clause
| UC-04 |
|---|
Find records in the table by a custom SQL
| UC-05 |
|---|
One-to-one relationship
In this example use case, a Driver owns a Car and only one Car. Note that the foreign key field exists on the owned item.
| UC-06 |
|---|
One-to-many relationship
| UC-07 |
|---|
Many-to-many relationship
9. Class Skeletons
How to you plan to implement the typical static find-calls? Have you thought about __callStatic()?
I love this.........
haha just like ruby on rail...
but why must using php 5.3?
I personnaly do love this pattern (ActiveRecord) ; anyhow, I'm wondering if two so close but so different patterns (ActiveRecord / DB Table Row Gateway) implemented in the same framework is not too much...
Still, I would love such a component ![]()
This looks quite good... but... I don't want to sound rude or anything, but wouldn't it be more beneficial for everyone to concentrate efforts on a single ORM library, like Doctrine?
Wouldn't it be better to handle the relationsships in an protected variable $_relations, $_relationsships or something alike, rather than an initialization function (maybe making init function optional).
Relationsships are more an description of an object rather than something that has to be "initialized" in a function.
But maybe this is just the request of a nitpicker...
Also there is currently no UseCase for the integration of Validators on certain ActiveRecord fields, I would like to see how that might be integrated and configured.
Hi Ken, if you want to start working with this before 5.3, I've found an alternative solution for those static calls:
Hope it helps,
Aldemar
The problem is in how you can get the class name in a static method from the parent. So, get_static_class() is the functionality that is really truly missing here.
Ken, this is exactly what I'm using right now in my active record approach and works perfect. Since the init method returns already an instance of Person and not Zend_Db_ActiveRecord_Abstract, calling from the parent any function using $this (meaning not static call) will use Person and then Zend_Db_ActiveRecord_Abstract.
The truly viable way to do this is to do something like this:
I guess I can create something like this for < 5.3 as well.
IMHO, I prefer:
instead of:
The first one will reflect better how it's actually going to work, btw, in my implementation I have an interface with that init() method defined, so, that ensures that every class you create has the init() method.
I wanna that you think about inheritance. Hibernate have 3 way to make it, for 3 different environment. The Joined inheritance is most common. The way consist in 2 classes in your project and you have 2 tables in database scheme. I wanna a code like this:
This code reflect my intention. So think about this.
Regards
I wanna that you think about inheritance. Hibernate have 3 way to make it, for 3 different environment. The Joined inheritance is most common. The way consist in 2 classes in your project and you have 2 tables in database scheme. I wanna a code like this:
SQL create table scheme.
PHP code wanted
This code reflect my intention. So think about this.
Regards
ZF Home Page
Code Browser
Wiki Dashboard
Woohoo!