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.

The difference between a ORM and AR

April 13, 2009 1:42pm

Subscribe [3]
  • #1 / Apr 13, 2009 1:42pm

    Xeoncross

    350 posts

    Well, I have been trying to figure out which one is which one but it seems like every time I get the definition down that I am told by someone else that I have it wrong. So here is what I have so far and I would like to know if this is right or just what I am missing.

    ORM (Object-relational mapping) is a object/class within a language like PHP that allows us to deal with data in the DB without dealing with the database itself (Writing SQL for MySQL).

    $orm->select('id, name');
    $result = $orm->get('email');

    AR (Active Record). A database table or view is wrapped into a class, thus an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save.

    $row = new mytableobject();
    
    $row->title = 'Hello World';
    $row->date = time();
    
    $row->save();


    Yet, according to this the “AR” class of CodeIgniter is really a ORM. So where am I messed up and what is missing from this?

  • #2 / Apr 13, 2009 3:42pm

    garymardell

    315 posts

    Codeigniter’s active record is basically just a query builder, nothing more.

  • #3 / Apr 13, 2009 3:48pm

    Xeoncross

    350 posts

    Yes, it is just a query builder. That sounds like an ORM to me because it is the object between your system and the database.

  • #4 / Apr 13, 2009 5:02pm

    jalalski

    113 posts

    An ORM provides a mapping between the database structures and an object system, Active Record just helps you put together SQL queries.

  • #5 / Apr 13, 2009 5:16pm

    Xeoncross

    350 posts

    According to Wikipedia you are half right. Which is where I am stuck. There doesn’t seem to be a solid line between what functionallity is part of a ORM and what is part of a AR.

    A database table or view is wrapped into a class, thus an object instance is tied to a single row in the table. - AR

    But in the case of the CI AR it the DB object is not tied in anyway to a certain table let alone a certain row. This is what it would look like in code:

    part = new Part()
    part.name = "Sample part"
    part.price = 123.45
    part.save()
  • #6 / Apr 13, 2009 6:04pm

    m4rw3r

    647 posts

    Wall of text warning! (I like this subject 😛)

    An ORM is a series of tools (loosely or tightly integrated depends) which maps database rows to objects in the application.

    Active Record is one type of ORM pattern, the other (somewhat) widely known type is the DataMapper pattern (not to be confused with Datamapper ORM for CI, it uses the Active Record pattern).

    Active Record:
    In the Active Record pattern the data objects themselves has a single static connection to the database which they share, but each object is responsible for the direct interaction.
    So if you call save() on an object, then that objects collects its data and constructs a query from that and calls the database.

    If you print_r() an Active Record object, it will show you all the internal properties which handles the database connection, column assignment, relation handling etc. This is quite an annoyance if you debug something and get a large dump (it can be similar with tightly tied data objects in the Data Mapper pattern, but there it is only one property to ignore).
    The other downside with this approach is that you have duplicate data in the form of all the settings in the Active Record objects.

    The name Active Record comes from that the records (objects which maps to a row, ie. data objects) are “active” and interacts directly with the database. Data Mapper data objects are “passive” objects, instead letting another object interact for them.

    Pros:
    - Easy to start with (usually)
    - Data objects are decoupled from other data objects
    - Easier to implement

    Cons:
    - Bloated objects
    - Duplicate data
    - The data objects store both the data and the logic to fetch it
    - No central point in the interaction chain

    Data Mapper:
    In the Data Mapper pattern, the data objects do not know anything about SQL or database connections. Instead they have a mapper which they send themselves to.
    The mapper constructs sql (or whatever) and also handles the database connection (can also be handled statically as in AR).
    So when you call save() on an object, it calls the mapper which receives the object and then saves it.

    But there are different types of Data Mapper implementations, where the objects are in some cases just normal StdClass objects and in other types (my IgnitedRecord included) they are special classes which redirect the limited data object functionality to the mapper (model in the case of IgnitedRecord).

    There are also two kinds of mappers, the hidden and the visible mapper. The hidden mapper is automatically instantiated by data objects and interacts with the database behind the scenes - you can actually never really call it in other cases than db settings management (if it is made properly)
    The visible mapper can you interact with directly, making the data objects less like Active Record objects and more of data-only objects - this kind of mapper is more like CI’s models.

    Pros:
    - The data and the logic is separated
    - The data objects does only contain the data, making them small
    - The mapper is the central point in the database interaction

    Cons:
    - More classes
    - Architecturally harder to implement, because of the different roles of the objects
    - Harder to get the grips of when starting (depends on the implementation)

    Examples:

    // Active Record
    $user = new User();
    $user->name = 'Martin';
    $user->save();
    $user2 = new User(array('name' => 'Chris')); // fetch user with the name Chris
    // ...
    
    // Data Mapper, hidden mapper
    $user = new User();  // connects to a mapper instance
    $user->name = 'Martin';
    $user->save();   // calls the mapper with the data of this object
    $user2 = new User(array('name' => 'Chris')); // same as AR, but it calls the mapper with the filtering data
    // ...
    
    // Data Mapper, visible mapper
    $user = $mapper->create_user(); // or whatever method the mapper has for object creation
    $user->name = 'Martin';
    
    $user->save(); // calls mapper
    // or
    $mapper->save($user); // a variant, with this variant the data object don't need to have a link to the mapper and can be a StdClass
    
    $user2 = $mapper->fetch_by(array('name' => 'Chris'));

    CodeIgniter’s ActiveRecord
    CI’s AR is strictly a SQL-string builder, nothing more nothing less. It is NOT an ORM because it does not map a specific object to a row or table in the database.
    Instead it helps the user to construct the sql, making it easier to create an ORM.

    So, to put it bluntly, CI’s AR doesn’t have anything to do in this thread other than as a SQL-builder.

    Summary:
    Both Active Record and the Data Mapper patterns are patterns for Object-Relational-Mapping.
    This makes the difference between an ORM and AR none, because AR is a type of ORM.

  • #7 / Apr 13, 2009 6:12pm

    Xeoncross

    350 posts

    Thank you for that complex answer. I must admit that I am having trouble wrapping my mind around some of it. 😉

    There are two reasons I am asking this, the first being the fact that I don’t know it and therefore have the responsibility to learn it. The second is that I made something that is very much like the “AR” CI uses just with the added ->save() function to each row result and I am not sure what it should be called.

    Based on what you just said, CodeIgniter is incorrect in calling their “Query Abstraction Class” an “Active Record” class, right?

  • #8 / Apr 13, 2009 6:23pm

    Colin Williams

    2601 posts

    According to Wikipedia you are half right

    😛 That should be on a t-shirt.

  • #9 / Apr 13, 2009 7:05pm

    m4rw3r

    647 posts

    Well, Code Igniter’s Active Record has two thing in common with the Active Record pattern, and that is the name and the fact that it builds and executes the query. 😉

  • #10 / Apr 13, 2009 7:41pm

    Xeoncross

    350 posts

    CI’s AR is strictly a SQL-string builder, nothing more nothing less. It is NOT an ORM because it does not map a specific object to a row or table in the database.

    Ok, so you are saying it is not an ORM as it only builds queries - which means it also can’t be the specialized ORM implementation “Active Record” right?

    Well, they have two thing in common with the Active Record pattern, and that is the name and the fact that it builds and executes the query. 😉

    Now you are saying that the CI AR class is in fact an AR implementation of an ORM?

    So which one of you’re-self is lying?  😛

  • #11 / Apr 13, 2009 7:45pm

    Colin Williams

    2601 posts

    This discussion is a bit useless. It’s really obvious what CI’s AR classes do. Get over what it is called.

  • #12 / Apr 13, 2009 7:50pm

    Xeoncross

    350 posts

    This topic isn’t because I am bored. It actually does have a purpose 😉
    As stated before…

    There are two reasons I am asking this, the first being the fact that I don’t know it and therefore have the responsibility to learn it. The second is that I made something that is very much like the “AR” CI uses… and I am not sure what it should be called.

  • #13 / Apr 13, 2009 7:51pm

    m4rw3r

    647 posts

    CI’s AR does not contain data, hence it is not an ORM.

    (m4rw3r 2: Ouch, that hurt, I also have the right to this brain we share, you know! 😛)

  • #14 / Apr 13, 2009 8:21pm

    Xeoncross

    350 posts

    In summary.

    CI’s AR does not contain data, hence it is not an ORM.

    Both Active Record and the Data Mapper patterns are patterns for Object-Relational-Mapping. This makes the difference between an ORM and AR none, because AR is a type of ORM.

    So the CodeIgniter Database should not be called an “Active Record” and the thing I built that is just like it should also not be called an “Active Record” (or even an ORM for that matter).

    This leaves my DB class (and the CI one) to use the less-cool name “Query Abstraction Layer” as that is all both our classes do. Correct?

    What about the result->save() function I have added - is that enough by itself to earn the title of AR or ORM?

    $query = $this->db->get('table');
    
    foreach ($query->result() as $row)
    {
       $row->title = 'new title';
       $row->save();
    }
  • #15 / Apr 13, 2009 8:31pm

    m4rw3r

    647 posts

    Well, QAL does not sound too bad. Active Record has a bit more “action” in it though. 😉
    So, yes CI’s Active Record should be called Query-Abstraction-Layer or something similar.

    The result::save() function you have there is an extremely small and bare-bones implementation of Active Record.
    (I think, because you may have a hidden mapper, right? 😛)

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

ExpressionEngine News!

#eecms, #events, #releases