Not a developer? Go to MovableType.com

Documentation

Interacting with MT::Objects: loading, creating and saving

All Movable Type Objects support a standard set of calls that can be used to load, save and remove objects from the database. These methods are:

  • new()
  • save()
  • load($terms, $arguments)
  • load_iter($terms, $arguments)
  • remove($terms, $arguments)
  • remove_all
  • count($terms)
  • exists($terms)
  • clone()

Let’s look at each in more detail.

new()

The new() method is used to instantiate a new object in the database. The object is not physically created until save() is called subsequently.

my $foo = MT::Foo->new;
$foo->property('bar');
$foo->save();

The new() method takes no arguments, and simply initializes a new in-memory object.

save()

To save an object call the save method:

$foo->save();

On success, save will return some true value; on failure, it will return “undef”, and you can retrieve the error message by calling the errstr method on the object:

$foo->save
    or die "Saving foo failed: ", $foo->errstr;

If you are saving objects in a loop, take a look at the “Note on object locking”.

load()

The load method can be used to load objects from the database. The load method can be used to compose queries that are both simple extraordinarily powerful. In fact the majority of queries that can be expressed in SQL can be represented by a call to the load() method.

As a result, the syntax for the load method is far too complex to discuss in complete detail here. For a complete description of load and its many facets, please consult Appendix B: MT::Object POD Documentation. What follows are just the basics of the load method.

The load method can be used to load a single object or multiple objects from the database. What is returned depends largely upon the context in which load is called. Take for example the following:

my $object = MT::Foo->load( $id );

my @objects = MT::Foo->load(\%terms, \%arguments);

You will notice that when load is called with a single scalar as input, load will attempt to look up the object in the database corresponding to that ID and return it. If load is called in an array context as in the second example, then load will return an array of objects.

Most commonly load takes two arguments as input:

  • a hash containing the query terms or constraints (e.g. load user whose favorite color is blue)

  • an hash containing the arguments for the query (e.g. limit the results of the query to 10, or sort the results by first name)

Valid arguments are:

  • sort - the column to sort by

  • direction - To be used together with a scalar sort value; specifies the sort order (ascending or descending). The default is “ascend”.

  • limit - Rather than loading all of the matching objects (the default), load only “N” objects.

  • offset - To be used together with limit; rather than returning the first “N” matches (the default), return matches “M” through “N + M”.

  • lastn

  • start_val - To be used together with limit and sort; rather than returning the first “N” matches, return the first “N” matches where “column” (the sort column) is greater than “value”.

  • range - specifies that the specific column should be searched for a range of values, rather than one specific value.

  • range_incl - Like the ‘range’ attribute, but defines an inclusive range.

  • join - can be used to select a set of objects based on criteria, or sorted by criteria, from another set of objects.

  • unique - Boolean flag that ensures that the objects being returned are unique.

Let’s look at a complete example:

my @objects = MT::Foo->load(
    { 
        title => "Hello World",
        foo => "bar",
    }, {
        sort => 'created_on',
        direction => 'ascend',
    }
);

load_iter()

The load_iter method returns an “iterator” that can be invoked to move though a dataset one item at a time. This technique is especially useful when working is large datasets because it progressively loads data from the database as needed.

my $iter = MT::Foo->load_iter({ foo => 'bar' });
while (my $foo = $iter->()) {
    $foo->remove;
}

The load_iter method supports one argument that load does not: window_size.

The window_size parameter is useful because it limits how many objects are loaded from the database at a time and can greatly reduce memory consumption. For example, when calling load_iter in order to iterate over each object in the database, load_iter will by default load 100 records at a time. Doing so limits the number of queries to the database Movable Type must make to load one item after another. The window_size argument adjusts the number of objects to load at a time.

remove()

To remove an object from the datastore, call the remove method on an object that you have already loaded using load:

$foo->remove();

On success, remove will return some true value; on failure, it will return “undef”, and you can retrieve the error message by calling the errstr method on the object:

$foo->remove
    or die "Removing foo failed: ", $foo->errstr;

You can restrict what specific objects you remove or delete by passing to the remove() method a hash containing the constraints for the request. For example:

MT::Foo->remove({ bar => 'baz' });

The terms you specify to remove by should be indexed columns. This method will load the object and remove it, and then fire the callback operations associated with those operations.

remove_all()

To quickly remove all of the objects of a particular class, call the remove_all method on the class name in question:

MT::Foo->remove_all();

On success, remove_all will return some true value; on failure, it will return “undef”, and you can retrieve the error message by calling the errstr method on the class name:

MT::Foo->remove_all
    or die "Removing all foo objects failed: ", MT::Foo->errstr;

count()

To determine how many objects meeting a particular set of conditions exist, use the count method:

my $count = MT::Foo->count({ foo => 'bar' });

The count method takes the same arguments as load and load_iter.

exist() and exists()

To check and see if an object that you have instantiated already exists in the database, use the exists method:

if ($foo->exists) {
    print "Foo $foo already exists!";
}

To test to see if an object with specific properties exists in the database, use the exist method:

if (MT::Foo->exist( { foo => 'bar' })) {
    print "Already exists!";
}

Tip: Calling exist is faster than issuing a count call.

clone()

Returns a clone of $obj. That is, a distinct object which has all the same data stored within it. Changing values within one object does not modify the other.

An optional “except” parameter may be provided to exclude particular columns from the cloning operation. For example, the following would clone the elements of the blog except the name attribute.

$blog->clone({ except => { name => 1 } });

$obj->clone_all()

Similar to the “clone” method, but also makes a clones the metadata information.

Back

1 Comment

jtoews

jtoews on March 30, 2010, 2:37 p.m. Reply

Reference to “Appendix B: MT::Object POD Documentation” seems wrong, or the doc is missing. Relevant info seems to be in “MT::Object Reference: Table of Contents”. See: http://www.movabletype.org/documentation/developer/objects/loading-an-existing-object-or-objects.html