ORM: Change parent's "updated_at" timestamps when model gets updated in FuelPHP

400 views Asked by At

Let's say I have a Model_Post that has_may Model_Comment.

Is there any way that the updated_at field of Model_Post gets updated every time that a new comment is saved? I checked the documentation for the observers, but I cannot find how to do that in a "ORM way".

This code doesn't seem to work:

class Model_Comment extends \Orm\Model
{
    protected static $_properties = array(
        'id',
        'post_id',
        'text',

    );
    protected static $_belongs_to = array('post');
    protected static $_observers  = array(
        'Orm\\Observer_UpdatedAt' => array(
            'events'          => array('before_save'),
            'relations'       => array('post')
        )
    );
}

class Model_Post extends Model
{

    protected static $_properties = array(
        'id',
        'title',
        'text',
        'updated_at'
    );
    protected static $_has_many   = array('comments');
}

I create a new comment using this code:

$comment             = Model_Comment::forge();
$comment->message_id = Input::post('message_id');
$comment->text       = Input::post('text');
$comment->save();
3

There are 3 answers

0
Daniel On BEST ANSWER

Finally I found the way to do that thanks to Uru's comments.

This code works now as I wanted; it was simpler than I thought.

Models:

class Model_Comment extends \Orm\Model
{
    protected static $_properties = array(
        'id',
        'post_id',
        'text',
    );
    protected static $_belongs_to = array('post');
}

class Model_Post extends \Orm\Model
{
    protected static $_properties = array(
        'id',
        'title',
        'text',
        'updated_at'
    );
    protected static $_has_many  = array('comments');
    protected static $_observers = array('Orm\Observer_UpdatedAt');
 }

And in the controller:

$comment       = Model_Comment::forge();
$comment->text = Input::post('text');
$parent_post   = Model_Message::find(Input::post('post_id'));

$parent_post->comments[] = $comment;
$parent_post->save();
1
Michael Martin On

Instead of mucking about with observers, seeing as you want an ORM-centric approach, you can fetch the parent, update its updated_at, then commit both objects to the DB via the ORM.

However, you're not implementing the whole observer config:. You're missing the property key, and the mysql_timestamp key.

// Adding it with config:
// - only needs to run on before_save
// - use mysql timestamp (uses UNIX timestamp by default)
// - use just "updated" instead of "updated_at"
protected static $_observers = array(
    'Orm\\Observer_UpdatedAt' => array(
        'events' => array('before_save'),
        'mysql_timestamp' => true,
        'property' => 'updated',
        'relations' => array(
            'my_relation',
        ),
    ),
);

FuelPHP Observer_UpdatedAt

6
Emlyn On

If you use the relations property of the observer config you can have the updated_at update when relations change. As long as your child model has a relation to the parent model you can add the relation name into the relations property and the ORM will do the rest for you when you save the model.

Please see the first paragraph under the code sample in the documentation.