NYCPHP Meetup

NYPHP.org

[nycphp-talk] Cake PHP and "Active Records"

Derek DeVries devrieda at gmail.com
Fri Sep 29 12:30:39 EDT 2006


<snip>
   One of the interesting questions is early loading versus lazy
loading.  The Active Record from Ruby on Rails,  for instance,  lazy
loads everything and caches nothing.  When you ask for 'User.name',
Ruby immediately does something like

SELECT name from user where id=66;
</snip>


Actually, in Rails the following occurs:

>> User.name
NoMethodError: undefined method `name' for User:Class
        from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1129:in
`method_missing'
        from (irb):1

FYI, you can't do this. User is a class, so you need to first find an
user object whose attributes you want to get the records for.

>> user = User.find(1)

This will execute the SQL query:
SELECT * FROM users WHERE (users.id = 1) LIMIT 1

>> puts user.name
=> derek

This will execute the SQL query:
SHOW FIELDS FROM users

BUT... Only in development mode. On production it caches this info and
no sql is executed

>> puts user.email
=> devrieda at gmail.com

now, no SQL query is executed. We've already introspected the db.


As far as eager loading sql queries, Rails has a method of doing this.
The sql for finding all comments could be written as

>> user = User.find(1, :include => :comments)

This would generate a single sql query to retrieve the user and all
associated comments so that you can now do:

>> for comment in user.comments
>>   puts comment.body
>> end

This can also cascade as much as you want and continues to only
perform one db query.

>> user = User.find(1, :include=>{:posts=>[:comments, :categorizations]})

a better explanation of how it works can be found here:
http://blog.caboo.se/articles/2006/02/21/eager-loading-with-cascaded-associations

This is very possible in php, and I've written an implementation of
ActiveRecord in PHP that uses the following syntax:

>> $user = User::find(1, array('include' => array('posts' =>
array('comments', 'categorizations'))));

which can do something like this with the resulting data:
>> foreach ($user->posts as $post) {
>>     print $post->title;
>>
>>     foreach ($post->comments as $comment) {
>>         print $comment->body;
>>     }
>>     foreach ($post->categorizations as $comment) {
>>         print $categorizations->name;
>>     }
>> }

not terribly pretty with all the array(array(array())), but it's what
we have to work with in PHP. this can get slow when there are many
associations for the active record objects, and many records are being
loaded from the db. Our own application however doesn't seem to have
any problems because we tend to use paging on any items that tend to
appear in sets greater than 250 records in the interface.



More information about the talk mailing list