Revision #16 has been created by samdark on Nov 26, 2019, 9:22:10 AM with the memo:
Fix typos
« previous (#15) next (#17) »
Changes
Title
unchanged
UUID instead of an auto-increment integer for ID with Active Record
Category
unchanged
How-tos
Yii version
unchanged
2.0
Tags
unchanged
mysql,active record,REST,UUID
Content
changed
> I have a dream ...
> I am happy to join with you today in what will go down in history as the
> greatest demonstration of
bad design of Active Record.[...]
How do we get the `{id}`? The essential solutuion is UUID generated by a client. It allows API application to be stateless and scale it, use master-master replication for databases and feel yourself a modern guy.
If you have Postgres -— lucky you, feel free to use the built-in UUID data type and close this article.
With MySQL the essential solution is [insert into users values(unhex(replace(uuid(),'-',''))...](https://mysqlserverteam.com/storing-uuid-values-in-mysql-tables/)
MySQL team recommends updating our INSERT queries. With Active Record it is not really possible.
For fetching UUIDs it recommends adding a virtual column
-— this can be used.
If you design the application from ground up, you can use defferent fields for a binary and text representation of UUID, and reference them in different parts of an application, but I am bound to the legacy code.[...]
Here's the hack:
Step 1. Add a `private
`$idText
;` property
```php[...]
// convert UUID from text value to binary and store the text value in a private variable
// this is a workaround for lack of mapping in active record
['id','filter','skipOnError' =>
true, 'filter'
=>
function($uuid)
{
$this->idText = $uuid;
return pack("H*", str_replace('-', '', $uuid));
}],
//now let's check if ID is taken
['id','unique','filter'
=>
function(\yii\db\Query $q)
{ {
$q->where(['id'
=>
$this->getAttribute('id')]);
}],
```
First rule is a validator for an input. Second rule is a filter preparing UUID to be written in a binary format and keeping the text form for output. Third one is a validator running a query over the binary value generated by a filter.
> Note: I wrote `$this->getAttribute('id')`, `$this->id` returns a text form.
We can write a query to validate data, not to save it.
Step 3. Add getters[...]
```
Step 5. Use Object Relation Mapping in Yii 3 when it's available and write simple mapping instead.