How ActiveRecord Works in phptarsier
It's Ruby on Rails, almost...
One of the great features about Ruby on Rails is its data model
implementation in the form of ActiveRecord. It's really impressive the
way it was implemented which really makes it promising. There has been
some attempts to port that feature into PHP but I was not able to see
an implementation that looks more like it.
In my attempt to create phptarsier, it was one of the things that I have to make sure it works closer to ActiveRecord in Rails.
Database Configuration
Before you run your application, you need to edit the config/config.php
file for you to get started. This will setup the database connection
for you and all your models will have the same connection as you
instantiate them.
Data Model
Now you have setup your database connection, you need to setup your
models for your database. Models are like representations of database
tables. For example, if you have a table name "blogs", you would define
your model like the following:
<?php
class Blog extends ActiveRecordBase {
public function table_name() {
return "blogs";
}
public function primary_key() {
return "id";
}
}
?>
As a general rule for phptarsier models, you have to name the above
file as app/models/Blog.php. The file should represent the model,
always keep that in mind. If we create a model, we need to extend the
functionality of ActiveRecordBase class to enable our model to perform
the way we want it to do. All the methods and properties in
ActiveRecordBase class is now inherited by our model. You might have
notice that I have implemented two methods, namely: table_name() and
primary_key(). Actually, this overrides the same methods implemented in
our base class. Why I suggest you to create your model like this, is to
gain a little time. It is important for me, but if its not a great deal
for you, you may not declare the two methods. With the above
implementation, the table name and primary key are automatically
returned and the object will not have to gather its information by
querying the database.
Given that class, you can now perform the basic
CRUD(create-retrieve-update-delete) operations. The following are example
implementations.
CREATE an Entry
<?php
...
$Blog = new Blog();
$Blog->create(array(
'title' => 'My first blog',
'author' => 'jbeduya',
'intro_text' => 'An introduction to my first blog.',
'body' => 'The content of my first blog! Wow!'
));
...
?>
UPDATE an Entry
<?php
...
$Blog = new Blog();
$blog = $Blog->find(1);
$blog->title = "My First Blog's new title";
$blog->save();
...
?>
The $Blog->find(1) is then converted to some SQL statement that
looks like this: SELECT * FROM blogs WHERE id=1. With the given query
it returns an object that has all the fields for the blogs table. The
next statement, updates the title to some other value and then updates
the database with the changes. That's how easy it is.
DELETE an Entry
<?php
...
$Blog = new Blog();
$Blog->find(1)->delete();
...
?>
The above simply tells the object to query this row and delete it. That simple.
Model Relationships
We are doing fine and we can now create models for each and every table
in our database. But what if we want to make some relationships our
models. As with my example, a blog has comments. First we need to
create our comment model that will look like the following:
<?php
class Comment extends ActiveRecordBase {
public function table_name() {
return "comments";
}
public function primary_key() {
return "id";
}
}
?>
How
are we gonna make that relationship, that every blog has many comments?
It is simple and it requires only a few lines of codes. We need to
update our Blog model to tell it has many comments. Our new Blog model
should have the following codes added:
<?php
....
class Blog extends ActiveRecordBase {
public function __construct() {
$this->has_many('comments', array(
t_class_name => 'Comment',
t_foreign_key => 'blog_id',
t_reference_key => 'id'
));
}
...
}
?>
The
above code simply tells that each row of Blog has many "comments", as
specified in the first parameter. The first parameter seves as the
relationship to the model. The second parameter which is an array of
some contants with values are additional parameters required to
properly associate the given relationship. If we have to read it, blog
has many comments, to determine its comments you instantiate the class
named 'Comment' and check if the value for blog_id in 'Comment' is the
same as my id. With that specified, you can simply perform the
following query.
<?php
...
$Blog = new Blog();
$blog = $Blog->find(1);
$comments = $blog->comments->find_all();
while ($comment = $comments->each()) {
echo $comment->comment; // displays the comment itself.
}
...
?>
The
"comments" property is automatically known by the class because of the
relationship that we specified. The above statment simply queries the
database for all the comments of the given blog.
find_by_<field(s)> and find_all_by_<field(s)>
One of the new implementations of ActiveRecordBase is the use of find_by and find_all_by clause.
<?php
...
$Blog = new Blog();
$blog = $Blog->find_by_title('How ActiveRecord Works in phptarsier');
echo $blog->author;
...
?>
That should pretty simple. It queries the blogs table using the
title field. It could even take additional fields by adding more fields and separating it with an
_and_.
<?php
...
$Blog = new Blog();
$blog = $Blog->find_by_title_and_author('How ActiveRecord Works in phptarsier', 'jbeduya');
echo $blog->author;
...
?>
Isn't that neat? How about the following:
<?php
...
$Blog = new Blog();
$blog = $Blog->find_all_by_author('jbeduya', array(t_condition => 'title'));
echo $blog->author;
...
?>
Phew...
A new release is full-packed with new features:
- pjs (a phptarsier version of rjs)
- ajax and effects
- components
- etc...
I am currently working for its site and sample applications. Just wait till it comes out, you can email me if you want an early copy of it. By the way I have changed its License from GPL to MIT.
Enjoy.