Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CakePHP4-如何验证需要将数据保存到多个表中的表单_Php_Cakephp_Cakephp 4.x - Fatal编程技术网

CakePHP4-如何验证需要将数据保存到多个表中的表单

CakePHP4-如何验证需要将数据保存到多个表中的表单,php,cakephp,cakephp-4.x,Php,Cakephp,Cakephp 4.x,如果以前有人问过,我会道歉。我能找到的所有示例都是旧的或适用于CakePHP的旧版本,例如7年前 我在CakePHP4.1.6中有一个应用程序。数据库中的两个表分别称为tbl_users和tbl_orgs(“orgs”在本例中表示“组织”) 当我添加一个组织时,我还希望创建一个用户,该用户是组织内的主要联系人。这涉及在提交表单时保存到tbl_组织和tbl_用户表 我遇到的问题是如何让表单在提交时运行tbl_用户和tbl_组织的验证规则 这就是我们的应用程序当前的结构: 在src/Controll

如果以前有人问过,我会道歉。我能找到的所有示例都是旧的或适用于CakePHP的旧版本,例如7年前

我在CakePHP4.1.6中有一个应用程序。数据库中的两个表分别称为
tbl_users
tbl_orgs
(“orgs”在本例中表示“组织”)

当我添加一个组织时,我还希望创建一个用户,该用户是组织内的主要联系人。这涉及在提交表单时保存到
tbl_组织
tbl_用户

我遇到的问题是如何让表单在提交时运行
tbl_用户
tbl_组织
的验证规则

这就是我们的应用程序当前的结构:

src/Controller/TblOrgsController.php
中有一个名为
add()
的控制器方法。这是由
bake
生成的,最初用于将新组织插入
tbl_orgs
表中。在这一点上,它在
tbl_用户方面没有做任何事情
,但它在保存新组织和运行适当的验证规则方面起了作用

一个验证规则是
tbl_orgs
中的每个
companyname
记录必须是唯一的。如果您尝试插入多个名称为“My company Limited”的公司,则会出现验证错误“此公司名称已存在”:

虽然上述适用于
TblOrgs
我们在
TblUsers
中还有一个
buildRules()
,它在
电子邮件
字段上应用类似的逻辑,以确保每个用户的所有电子邮件地址都是唯一的

add()
控制器方法中,我们首先为
TblOrgs
指定一个新的空实体:

// src/Controller/TblOrgsController.php
public function add()
{
    $org = $this->TblOrgs->newEmptyEntity();
    // ...
    $this->set(compact('org'));
}
创建表单时,我们传递
$org

// templates/TblOrgs/add.php
<?= $this->Form->create($org) ?>
<?= $this->Form->control('companyname') ?>
<?= $this->Form->end() ?>
它还根据
buildRules
中为
TblOrgs
指定的规则工作。例如,如果我两次输入相同的公司名称,则会在行中显示相应的错误:

然后我尝试为
TblUsers
引入字段。我在表单字段前面加了点符号,例如,这是为了对应
tbl_用户。电子邮件
输入字段:

<?= $this->Form->control('TblUser.email') ?>
在这种情况下,
Tags
Comments
是不同的模型,但是
newEmtpyEntity()
对两者都适用。考虑到这一点,我将我的
add()
方法改编为:

$org = $this->TblOrgs->TblUsers->newEmptyEntity();
但这现在为
TblUsers
提供了一个实体。看起来你可以有一个或另一个,但不能两者都有

这对我的用例不起作用的原因是,我可以运行
TblOrgs
(但不能运行
TblUsers
)的验证规则,反之亦然

您如何将其设置为运行两个模型的验证规则?表单可能需要将数据保存到多个表中,并且希望每个表的验证规则都能运行,这似乎不是一个不合理的要求。我从文档中得到的印象是这是可能的,但不清楚如何实现

作为参考,两个表之间存在适当的关系:

// src/Model/Table/TblOrgsTable.php
public function initialize(array $config): void
{
    $this->hasMany('TblUsers', [
        'foreignKey' => 'o_id',
        'joinType' => 'INNER',
    ]);
}


好的,这里有很多困惑需要澄清。:-)根据您所写的内容,我在这里的假设是,您试图使用一个表单来添加一个新组织,以及其中的第一个用户,然后可能稍后您将向该组织添加更多用户

首先,
$this->TblOrgs->TblUsers
是您的用户表对象,因此当您使用

$org = $this->TblOrgs->TblUsers->newEmptyEntity();
您正在做的是创建一个新的用户实体。事实上,您通过orgs表访问该表对象,并将其称为
$org
,这并没有改变这一点。它不会神奇地创建一个包含空白用户实体的空白组织实体。但这里根本不需要实体结构,只需要空的组织实体。简单地回到:

$org = $this->TblOrgs->newEmptyEntity();
现在,在您的表单中,您将需要以下内容:

<?= $this->Form->create($org) ?>
<?= $this->Form->control('companyname') ?>
<?= $this->Form->control('tbl_users.0.email') ?>
<?= $this->Form->end() ?>

该字段称为
tbl_users.0。电子邮件
,因为:

  • 表名转换为小写下划线格式
  • 这是一个从组织到用户的关系,所以它需要一个用户数组;我们必须为该数组提供一个数字索引,0是一个很好的起点。如果要同时添加第二个用户,则该字段应为
    tbl_users.1.电子邮件
  • 注意:了解表单助手希望您使用何种格式创建字段名的一个好方法是从数据库(在本例中为组织及其用户)中读取一组现有记录,然后使用类似于
    debug($org)的方法转储该数据。您将看到,
    $org
    有一个名为
    tbl_users
    的属性,它是一个数组,直接指向我上面描述的这个结构

    通过这样设置字段,您应该能够将生成的数据直接修补到控制器中的
    $org
    实体中,并将其保存,而无需任何其他工作。修补程序将创建整个结构,其中包含一个类为
    TblOrg
    的实体,以及一个
    tbl\u users
    属性,该属性是一个数组,其中包含一个类为
    TblUser
    的实体,并且将对这两个实体进行验证。(至少应该是这样;您可以使用上面提到的
    debug($org);
    进行确认。)当您保存此实体时,它将首先保存
    TblOrg
    实体,然后在保存之前将新ID添加到
    TblUser
    实体中,以及检查两者的规则,并确保如果不能全部保存,则不会将任何内容保存到数据库中。只需一次
    save
    呼叫,所有这些都会自动发生

    如果您的关联是hasOne或belongsTo关系(例如,如果您正在添加新的
    // src/Model/Table/TblUsersTable.php
    public function initialize(array $config): void
    {
        $this->belongsTo('TblOrgs', [
            'foreignKey' => 'o_id',
            'joinType' => 'INNER',
        ]);
    }
    
    $org = $this->TblOrgs->TblUsers->newEmptyEntity();
    
    $org = $this->TblOrgs->newEmptyEntity();
    
    <?= $this->Form->create($org) ?>
    <?= $this->Form->control('companyname') ?>
    <?= $this->Form->control('tbl_users.0.email') ?>
    <?= $this->Form->end() ?>