ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

ActiveRecord for CodeIgniter: Rails-style model interactions

September 20, 2007 9:14am

Subscribe [5]
  • #1 / Sep 20, 2007 9:14am

    Matthew Pennell's avatar

    Matthew Pennell

    221 posts

    Following on from this thread, I have now got my version of ActiveRecord (based on RoR’s implementation) to a point where I’d like to get some more pairs of eyes on it.

    I’ve written up the class and provided a download here:

    ActiveRecord Class on the wiki

    I’m using it at the moment on a project in development, and it seems to be working fine - no noticeable impact on performance or query speed, and it makes developing a lot faster without having to write CRUD functions for every single model.

    In summary, it means that you can do things like this without having to write all the database interaction code yourself:

    $me = $this->Person->find_by_first_name('Buddy');
    $me->fetch_related_pages();
    
    $new_page = new Page();
    $new_page->title = 'My Title';
    $new_page->content = 'Blah blah blah';
    $new_page->save();
    
    $me->create_relationship($new_page);

    Note that it’s PHP5 only.

  • #2 / Sep 20, 2007 11:32am

    alexsancho's avatar

    alexsancho

    42 posts

    Really nice addition, but i’m still looking for and update and update_by method, the class only contains methods to create new records, but how you update and existing one?

    Thanks again for your contribution

  • #3 / Sep 20, 2007 11:40am

    Matthew Pennell's avatar

    Matthew Pennell

    221 posts

    Really nice addition, but i’m still looking for and update and update_by method, the class only contains methods to create new records, but how you update and existing one?

    They’re on my development machine at home - I’ll update the class and the wiki when I get in to add the update method.

  • #4 / Sep 20, 2007 2:22pm

    Michael Wales's avatar

    Michael Wales

    2070 posts

    If you want to work on merging this with Fire (I saw your reply in regards to this) feel free to do so. The code is publicly available and you are more than welcome to take it over (just give me a credit line in your readme).

  • #5 / Sep 20, 2007 3:53pm

    Matthew Pennell's avatar

    Matthew Pennell

    221 posts

    They’re on my development machine at home - I’ll update the class and the wiki when I get in to add the update method.

    I’ve added the basic update() method to the downloadable code and the wiki article now. 😊

  • #6 / Sep 21, 2007 7:54am

    gunter's avatar

    gunter

    192 posts

    Hi!

    and how can I use the update() ??

    like this???

    $me = $this->Person->get_by_id($id);
    $me->fetch_related_pages();
    
    
    $me->title = 'New Title';
    $me->content = 'Blah blah blah';
    $me->save();

    edit: I forget to say wow! and thanks!!

  • #7 / Sep 21, 2007 8:32am

    Matthew Pennell's avatar

    Matthew Pennell

    221 posts

    and how can I use the update() ??

    Like this:

    $me = $this->Person->get_by_id($id);
    $me->title = 'New Title';
    $me->content = 'Blah blah blah';
    $me->update();
  • #8 / Sep 21, 2007 2:35pm

    danfreak's avatar

    danfreak

    99 posts

    Thanks for this nice library Buddy!

    I’ll check it out!

    Dan

  • #9 / Sep 21, 2007 3:17pm

    Michael Wales's avatar

    Michael Wales

    2070 posts

    I’ve been looking over this library since it was released - this is looking really, really, nice.

    Any chance of getting some better relationships involved? The relationships table you are employing (similar to RoR’s HABTM relationships) is a bit excessive for just a belongs_to or has_many relationship.

    For instance:

    Table: pages
    id
    user_id
    title
    body

    Table: users
    id
    username
    email

    Crating a pages_users table is a bit excessive and increases the number of calls made to the database, when a relationship could simply be formed between pages.user_id and users.id columns.

    I’ve yet to actually play with this library, so if it’s covered somewhere I haven’t read about yet, feel free to correct me.

    Great work though - I will definitely be using this in my next project.

  • #10 / Sep 21, 2007 5:45pm

    nmweb

    206 posts

    Great work, I really like it and am definitely gonna use it in my next project. I, however, need to tweak it to PHP4. At first glance this seems feasible, or is there anything exotic you used?

  • #11 / Sep 22, 2007 4:50am

    Matthew Pennell's avatar

    Matthew Pennell

    221 posts

    Any chance of getting some better relationships involved? The relationships table you are employing (similar to RoR’s HABTM relationships) is a bit excessive for just a belongs_to or has_many relationship.

    You’re right (and there isn’t any other kind of relationship defined). The difficulty is that there isn’t a built-in :has_many or similar pre-defined relationship archetypes like RoR has.

    Perhaps if you specify an array of relationships in the constructor of the model, something like this:

    <?php
    
    class Page extends ActiveRecord {
    
        function __construct()
        {
            parent::ActiveRecord();
            $this->_class_name = strtolower(get_class($this));
            $this->_table = $this->_class_name . 's';
            $this->_has_one = array('author');
            $this->_belongs_to = array('site');
            $this->_has_and_belongs_to_many = array('resource');
            $this->_columns = $this->discover_table_columns();
        }
        
    }
    
    ?>

    And then the create_relationship() and fetch_related() functions would refer to those relationship properties when building their queries.

    Does that make sense?

  • #12 / Sep 22, 2007 4:57am

    Matthew Pennell's avatar

    Matthew Pennell

    221 posts

    Great work, I really like it and am definitely gonna use it in my next project. I, however, need to tweak it to PHP4. At first glance this seems feasible, or is there anything exotic you used?

    I’m afraid it’s impossible (AFAIK) to convert this to PHP4, due to its use of the __call() function. It catches any calls to non-existent methods, such as find_by_my_random_database_field(‘foobar’), and re-routes them to the right method - in that example, it would end up at find_by(‘my_random_database_field’, ‘foobar’). You can’t replicate that in PHP4 without creating all those find and fetch methods explicitly, which would be far too much work.

    Read more about PHP5’s overloading here

  • #13 / Sep 22, 2007 5:32am

    nmweb

    206 posts

    Great work, I really like it and am definitely gonna use it in my next project. I, however, need to tweak it to PHP4. At first glance this seems feasible, or is there anything exotic you used?

    I’m afraid it’s impossible (AFAIK) to convert this to PHP4, due to its use of the __call() function. It catches any calls to non-existent methods, such as find_by_my_random_database_field(‘foobar’), and re-routes them to the right method - in that example, it would end up at find_by(‘my_random_database_field’, ‘foobar’). You can’t replicate that in PHP4 without creating all those find and fetch methods explicitly, which would be far too much work.

    Read more about PHP5’s overloading here

    Thanks but the problem fixed itself on my side. My host is about to move me to the php5 server. I indeed was afraid the __call() would be problematic.

  • #14 / Sep 22, 2007 6:14am

    danfreak's avatar

    danfreak

    99 posts

    About relationships:

    Why don’t go for some conventions a bit like in CakePHP?

    For example, if in the table “users” we have a field “group_id”, the foreign key for our hasMany relationship is “foreign-key-table-name_id”.

    Just an idea…

    Dan

  • #15 / Sep 23, 2007 4:35am

    gunter's avatar

    gunter

    192 posts

    I have a sunday question:

    $data['all_boxes'] = $this->Box->find_all_by_project($id); 
    $this->load->view('box_index',$data);

    Now I am getting 18 rows from the db
    but in the profiler I see that I have 18 queries: SHOW COLUMNS FROM box

    I donĀ“t believe that this makes a big performance problem, but it makes the profiler query section a lot more unreadable…
    so, how can I make it that $this->_columns = $this->discover_table_columns(); only sends the first time the query and then using a global variable or something like that…

    oh, in this moment I get it!  :lol: I can declare the colums by hand in the model with

    $this->_columns = array ('this','that')

    ...
    ...but for development it would be nice to use discover_table_columns(); (only once) - so, has anyone an idea?

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases