yii-starter-kit / yii2-starter-kit

Yii2 Starter Kit
http://yii2-starter-kit.terentev.net
Other
1.42k stars 648 forks source link

Cannot add or update a child row: rbac_auth_item #726

Closed itcgtaraz closed 4 years ago

itcgtaraz commented 4 years ago

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (eabase.rbac_auth_item, CONSTRAINT rbac_auth_item_ibfk_1 FOREIGN KEY (rule_name) REFERENCES rbac_auth_rule (name) ON DELETE SET NULL ON UPDATE CASCADE) The SQL being executed was: INSERT INTO rbac_auth_item (name, type, description, rule_name, data, created_at, updated_at) VALUES ('editor', 2, 'editor', '', '', NULL, NULL)

XzAeRo commented 4 years ago

Can you give some more context on what are you trying to achieve? Can you share a small snippet of code that leads to that error?

From what I can see, the error happens because you're trying to insert an element that already exists in the rbac_auth_item table.

itcgtaraz commented 4 years ago

I want to create a new auth_item. You can try it yourself. If I manually using SQL, for example: INSERT INTO rbac_auth_item (name, type,description, rule_name,data, created_at,updated_at) VALUES ('editSettings', 2, NULL, NULL, NULL, NULL, NULL), everything works.

rivieiraa commented 4 years ago

Link is always a good answer :-) https://www.yiiframework.com/doc/guide/2.0/en/security-authorization#using-migrations

XzAeRo commented 4 years ago

@itcgtaraz I just tried this code within a migration I created in the rbac migrations folder:

# file: common/migrations/rbac/m191120_093027_add_editor_role.php
<?php
use common\models\User;
use common\rbac\Migration;

class m191120_093027_add_editor_role extends Migration
{
    public function up()
    {
        // first we get the role to which we will attach the new role
        $managerRole = $this->auth->getRole(User::ROLE_MANAGER);

        // then we create the special permissions for this new role
        $editSettings = $this->auth->createPermission('editSettings');

        // then we create the new editor role
        $editorRole = $this->auth->createRole('editor'); // you should create a User::ROLE_EDITOR constant to use in here instead of just 'editor'

        // then we commit all our new data
        $this->auth->add($editorRole); // add new role
        $this->auth->add($editSettings); // add new permission
        $this->auth->addChild($editorRole, $editSettings); // append new permission to the new role, you may also want to append it to the manager role and administrator role
        $this->auth->addChild($managerRole, $editorRole); // we make the editor a child of manager (should have less privileges)
    }

   public function down(){...}

Then ran console/yii rbac-migrate/up. Which ran perfectly fine.

So, if you could provide some more context to see where your problem is, we could help you better. Also, you may want to check @rivieiraa link.

itcgtaraz commented 4 years ago

You can fix it. rule_name default is null. Gives an error when trying to add, because rule_name = ''

INSERT INTO rbac_auth_item (name, type, description, rule_name, data, created_at, updated_at) VALUES ('editor', 2, 'editor', '', '', NULL, NULL) INSERT INTO rbac_auth_item (name, type, description, rule_name, data, created_at, updated_at) VALUES ('editor', 2, 'editor', NULL, '', NULL, NULL)

itcgtaraz commented 4 years ago

replace yii2-starter-kit/backend/modules/rbac/models/RbacAuthItem.php

   public function rules()
    {
        return [
            [['name', 'type'], 'required'],
            [['type', 'created_at', 'updated_at'], 'integer'],
            [['description', 'data'], 'string'],
            [['name', 'rule_name'], 'string', 'max' => 64],
            [['rule_name'], 'exist', 'skipOnError' => true, 'targetClass' => RbacAuthRule::class, 'targetAttribute' => ['rule_name' => 'name']],
        ];
    }

on

    public function rules()
    {
        return [
            [['name', 'type'], 'required'],
            [['type', 'created_at', 'updated_at'], 'integer'],
            [['description', 'data'], 'string'],
            [['name', 'rule_name'], 'string', 'max' => 64],
            ['description', 'default', 'value' => null],
            ['rule_name', 'default', 'value' => null],
            ['data', 'default', 'value' => null],
            [['rule_name'], 'exist', 'skipOnError' => true, 'targetClass' => RbacAuthRule::class, 'targetAttribute' => ['rule_name' => 'name']],
        ];
    }