We have a usual workflow step that consist of git commit with DB migrations (it can be regarded as kind of unit of work). This commit goes to CI which do a magic with tests and deployment.
And now we want to remove unneeded \yii\rbac\Rule from file system and DB in one step (one commit). It is quite logical to remove RBAC Rules from DB via migration using a \yii\rbac\DbManager.
Files must be updated first to run migration and this action deletes Rule class file.
A Rule can be successfully deleted from DB _after_ its class was deleted from file system.
Error. Because the Rule's data can not be unserialized without the class.
I think it's a kludge to make such Rule removal by doing 2-step-deployment or remove it from DB manually.
| Q | A |
| --- | --- |
| Yii version | 2.0.9 |
| PHP version | |
| Operating system | |
How do you propose to do it in a single commit?
I propose to give RBAC Manager an ability to remove rules and items directly by name.
If I haven't lost sight of something, in the default implementation \yii\rbac\BaseManager::removeItem and \yii\rbac\BaseManager::removeRule uses object argument to take the name from it only.
The seconds option is to add public helper methods like remove[Item|Rule]ByName.
A Rule can be successfully deleted from DB after its class was deleted from file system.
I think it's wrong and should always be other way around i.e. if rule is still in DB but its class is missing you'll get an exception.
I agree that there should be an exception when a DB rule exists but the file doesn't. I'm not talking about any automatic deletion.
I mean there should be a safe and proper way to get rid of DB part of a rule if its class already doesn't exists any more.
The problem now is that we must pass an object of a rule to the remove method, but due to the class doesn't exists any more, the object neither can be created manually, nor can be fetched via RBAC manager (it can't be properly unserialized). So it is actually no standard way to remove the rule in this case.
Your case already causes trouble. If you're removing PHP class first, you'll get error from the moment it's removed till the moment migrations are applied. As I said, it should be other way around:
- Remove all usages of the rule from hierarchy.
- Remove class itself.
It's unable to do this in one step as I described.
Please do not focus on the case itself, it's special. I mentioned unit of work and CI. Just imagine it happens very fast with all possible blockings on the upgrade time, and nothing happens between removing the file and the rule from DB. I think it is a programmer responsibility what to do with sharpened tool. =)
I'm talking about how to remove rule from hierarchy by name only, without creating rule object. It is safe, so why not to allow it?
袗fter all there is always may be a situation of inconsistency when file is deleted (accidentally maybe) and DB part was forgotten. How to just drop it with rbac manager?
I don't like the idea of exposing raw deletion like that:
@yiisoft/core-developers need opinions.
It's unable to do this in one step as I described.
There is a workaround: you could attach copy of declaration of removed class in migration.
Migrations should not use code from the application that is subject to change. If you have a migration that adds a Rule class you can not run that migration when you have removed the class so you break your migration system. See the "Note" under this headline: http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#db-accessing-methods
Most helpful comment
Migrations should not use code from the application that is subject to change. If you have a migration that adds a Rule class you can not run that migration when you have removed the class so you break your migration system. See the "Note" under this headline: http://www.yiiframework.com/doc-2.0/guide-db-migrations.html#db-accessing-methods