-
I appreciate this is a bit of a niche issue, but I've run into what feels like a bug with keeping snapshots of model data when manually assigning data to a model via with the model I'm using Phalcon 4.1.2 with PHP 7.4.25 and have found that when you manually assign data to an instance of a
Below is a simplified example to show how to replicate the problem I've run into. I have a model called My models look like this: namespace App;
class Members extends \Phalcon\Mvc\Model
{
public $id;
public $title;
public $user_id;
public function initialize()
{
$this->setSource('members');
$this->keepSnapshots(true);
$this->belongsTo(
'user_id',
Users::class,
'id',
['alias' => 'User']
);
}
public function afterUpdate()
{
ray($this->getSnapshotData());
ray($this->getChangedFields());
}
}
class Users extends \Phalcon\Mvc\Model
{
public $id;
public $name;
public $deleted;
public function initialize()
{
$this->setSource('users');
}
} I am calling I want to verify ownership of records before users can view or update a record. An easy way to do this would be to join onto my Users model using my User ID to see if the record data is returned from the DB. To do this, I could use Phalcon's query builder in my controller update action to get the record. I've skipped checks on whether the record exists to keep things more concise: $builder = $this->modelsManager
->createBuilder()
->columns('m.*')
->from(['m' => Members::class])
->andWhere('m.id = :id: AND m.user_id = :user_id:', [
'id' => $this->request->getQuery('id'),
'user_id' => 1
])
->innerJoin(Users::class, 'u.id = m.user_id AND u.deleted = 0', 'u');
$target = $builder->getQuery()->execute()->getFirst();
$record = new Members($target->toArray());
var_dump($record); // data is correctly assigned to the model instance
$record->title = $this->request->getPost('title');
$record->update();
// exception gets thrown "The 'keepSnapshots' option must be enabled to track changes" If I skip all my access checks and simply use $record = Members::findFirstById($this->request->getQuery('id'));
$record->title = $this->request->getPost('title');
$record->update();
// no exception thrown, snapshots are being kept and record updated It would be awesome if it was possible to perform a custom DB query, manually assign the data back to the model and update as required whilst keeping snapshots. The only workaround I have is to do my access checks and then Am I going about this the wrong way? Is this a bug? Thanks in advance for your thoughts. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
This is unnecessary: $target = $builder->getQuery()->execute()->getFirst();
$record = new Members($target->toArray()); If your query is correct, $builder = $this->modelsManager
->createBuilder()
->columns('m.*')
->from(['m' => Members::class])
->andWhere('m.id = :id: AND m.user_id = :user_id:', [
'id' => $this->request->getQuery('id'),
'user_id' => 1
])
->innerJoin(Users::class, 'u.id = m.user_id AND u.deleted = 0', 'u');
$target = $builder->getQuery()->execute()->getFirst();
$target->title = $this->request->getPost('title');
$target->update(); |
Beta Was this translation helpful? Give feedback.
This is unnecessary:
If your query is correct,
$target
should be aMembers
object which can be updated right away.