验证外键的最佳方法是什么?

时间:2013-09-11 19:06:12

标签: php oop model

我遇到了一个问题,无法验证引用其他模型的模型。

我有'用户'模型和'个人资料'模型。我想创建配置文件,但我需要检查用户是否确实存在。

在我的个人资料模型中,我有一个方法'validateUser'但我要么必须在数据库中的特定表上写一个查询,要么我必须创建一个用户模型对象并调用exists(id)。

这两种选择似乎都有很多缺点。表名可以更改我必须查看使用它的所有模型。使用用户模式对象,我将不得不在配置文件模型中创建一个对象或注入它。

最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

厄运的领域..

在现实世界中,验证很少是一个简单的过程。相反,你有几个不相关的问题:

  • 检查实例内的数据是否与业务规则一致
  • 确保实例状态与其他域结构不冲突
  • 根据存储中的现有数据和约束验证信息的完整性

如果您使用活动记录来表示domain model (不要与MVC中的M混淆),则所有这三个方面都成为单个对象的责任。

你现在拥有的是什么。

但是有希望..

最好的选择是将所有这些责任分开(所有欢呼SRP。基本上你所做的是将你当前的设置划分为不同的结构组:

  • 域对象:用于处理域实体的特定规则

  • 数据映射器:用于存储抽象

  • 服务:用于域对象和映射器(或其他域对象)之间的交互

由于您的问题有些令人困惑(用户和个人资料以及保存和验证,然后有些东西不存在),我不确定我是否理解正确,但这是一个小例子:

public function createProfile( $id, $email, $name )
{
    $account = new Account;
    $account->setId( $id );

    $accountMapper = new AccountMapper( $pdo ); // explained below

    if ( $accountMapper->fetch( $account ) === false )
    {
        $this->errors[] = .. something about missing account
        return;
    }

    $profile = new Profile;
    $profile->setEmail( $email )
            ->setName( $name );

    if ( $profile->isValid() === false )
    {
        $this->errors[] = .. something about invalid profile
        return;
    }

    try
    {
        $profileMapper = new ProfileMapper( $pdo ); // explained below
        $profileMapper->store( $profile );
    }
    catch ( Exception $e )
    {
        $this->errrors[] = .. something about failing to create profile
        return;
    }

    $account->addProfile( $profile );
    $accountMapper->store( $account );
}

这是非常简化的示例。特别是在映射器被初始化的地方,因为在真实世界情况下的那部分将由某些工厂处理。有点像this post中描述的那样。

这里的要点是域数据的验证和DB完整性的保证是分开完成的。用于与数据库交互的底层API实际上会返回错误代码,如果您违反了UNIQUE KEYFOREIGN KEY或任何其他约束,您可以使用这些约束来确定出现了什么问题。

该方法本身将是服务的一部分(在这种情况下 - 一些管理用户帐户的服务)。

  

注意:如果您的应用程序需要为每个操作执行多个SQL交互,并且这些交互需要作为具有回滚功能的事务完成,那么,而不是直接使用数据映射器,你应该考虑实施Units of Work。要了解UoW,您必须阅读Patterns of Enterprise Application Architecture,因为这是非常广泛的主题。

相关问题