We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Update just one Model property

Hi,

I've got a model for which I would only like to update one property. I have the unique identifier for the model so know I can simply load the model, make the change, then save it again like so:

<?PHP

$Bill = Bill::findFirst($bill_id);
$Bill->paid = TRUE;
$Bill->save();

However, it seems like a waste to have to do a query to load the model first. So I tried something like this:

<?PHP
// in Bill class, set $this->useDynamicUpdate(true)

$Bill = new Bill();
$Bill->id = $bill_id;
$Bill->paid = TRUE;
$Bill->update();

But it had the same effect.

Basically I don't care what the other properties are, I just want to do the equivalent of this query:

UPDATE
    `test`
SET
    `paid` = 1
WHERE
    `id` = 10348


404
edited Oct '14

Use PHQL for that.

$phql = "UPDATE Bill SET paid = ?0 WHERE id = ?1";
$this->modelsManager->executeQuery($phql, array(
    0 => 1,
    1 => 10348
));

or

$phql = "UPDATE Bill SET paid = 1 WHERE id = 10348";
$this->modelsManager->executeQuery($phql);
$this->useDynamicUpdate(true);

@Phillipp - I know about useDynamicUpdate(), but that causes the model to only update those columns that have changed. Apparently though, if I create the model object like my second example, the model considers all columns to have been changed, and overwrites all columns - even the ones I don't set.

Yes, because a new (naked) instance is most likely treated like a new row in the table - only that you use it to update an existing row ;).



7.7k
$broadcaster->useDynamicUpdate(true);
$broadcaster->skipAttributesOnUpdate(array('creator', 'created', 'modified', 'modifier'));

When I remove the 'modified' and 'modifier' fields, I get an update to 'null' whenever I call the update() function. The only way I found around it is fetching the object, or calling with phql..

Anyone managed to solve that already?

edited Jul '15

I am using this solution:

Override the save() function

public function save($data = null, $whitelist = null) {
    if($data) {
        $this->skipAttributes(array_diff($this->getModelsMetaData()->getAttributes($this), array_keys($data)));
    }
    parent::save($data, $whitelist);
}

Then

$g = new Bill;
$g->save([
    'id' => '001',
    'paid' => true
]);

Hope this helps

I'm using a similar approuch:

public function update($data = null, $whiteList = null): bool
    {
        if($data) {
            $modelFields = $this->getModelsMetaData()->getAttributes($this);
            $this->skipAttributes(array_diff($modelFields, $data));
        }
        return parent::update($data, $whiteList);
    }

Then :

$bill = new Bill;
$bill->paid = true;
$result = $bill->update(['paid']);

The difference between @R3bm3v0N is we need to pass just fields to be will update and Phalcon will use the object value. Follow the MySql log result:

UPDATE `bill` SET `paid` = true WHERE `id` = 1