php - Eloquent ORM - 为什么 Laravel 不认为这两个对象是相同的?

标签 php laravel

我对 Laravel 还是很陌生。在我之后able to get multiple Eloquent relationships defined在两个模型之间,我注意到可以将实例传递给它不属于的父模型实例中的方法。所以我认为在方法本身内加强这种关系可能会很好。

在 Organization.php 中:

/**
 * @param \App\Contact The Contact to delete
 */
public function deleteContact(Contact $contact)
{
    if($contact->organization == $this)
    {
        $this->contacts->find($contact->id)->delete();
    }
    else
    {
        dd('Error: Contact ' . $contact->fname . ' ' . $contact->lname . ' #' . $contact->id . ' does not belong to Organization ' . $this->name . ' #' . $this->id);
    }
}

但是,在传递实际属于的联系人时,我不断收到自定义错误消息,或者至少我认为是这样!当我在 tinker 中测试关系时,它为 Bob 和 Bob 的组织返回了不同的实例 id

>>> $org = Organization::find(17)
=> App\Organization {#2929
     id: 17,
     name: "Test Org",
     primary_contact_id: 33,
   }
>>> $org->contacts
=> Illuminate\Database\Eloquent\Collection {#2925
     all: [
       App\Contact {#2926
         id: 33,
         organization_id: 17,
         fname: "Alice",
         lname: "Abbot",
       },
       App\Contact {#2943
         id: 34,
         organization_id: 17,
         fname: "Bob",
         lname: "Baker",
       },
     ],
   }
>>> $bob = Contact::find(34)
=> App\Contact {#2940
     id: 34,
     organization_id: 17,
     fname: "Bob",
     lname: "Baker",
   }
>>> $bob->organization == $org
=> false
>>> $bob->organization
=> App\Organization {#2932
     id: 17,
     name: "Test Org",
     primary_contact_id: 33,
   }

很明显,它是在比较两个不同的实例。为了解决这个问题,我不得不将条件更改为有效的 $contact->organization->id == $this->id 。然而,这样做就没那么 Eloquent 了。

  1. 为什么会生成两个不同的实例?这些后续调用应该(理论上)产生相同的实例(或者我认为如此)。

  2. 这种额外的保护是否有必要?由于内部代码,我们至少受到了部分保护,但不是我可以用 try/catch 包围并优雅地处理违规行为的东西——我需要先测试,然后尝试删除。 (如果传递的 Contact 不是 Organization 的有效相关实例,find() 返回 null,导致 PHP 错误而不是异常。)是否有更好的方法来执行此操作,还是我想多了?

最佳答案

从 Laravel 的角度来看,我们不能仅仅依靠相等运算符来比较对象,在 Eloquent 模型的情况下,这可能非常不可靠且难以比较。

正如@Devon 和@N Mahurin 所说的那样,如果您比较的是更可预测的 stdClass 对象,则使用相等运算符比较对象会很有效。

这在过去是一场斗争。还好这个PR在 5.3 中成为 Laravel 的核心。

要知道两个模型是否本质上相同,Laravel 检查是否

  1. 主键相同
  2. 同 table
  3. 数据库连接相同。

基于此,我们可以假设我们正在比较相等的两行。因此,在您的情况下,以下内容应该有效:

$bob->organization->is($org);

请引用documentation关于比较模型。

关于php - Eloquent ORM - 为什么 Laravel 不认为这两个对象是相同的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54152701/

相关文章:

laravel - Maatwebsite/Laravel-Excel 导入将特殊字符转换为数字 0

php - 如何在 View laravel blade 的类中添加运算符三元?

php-fpm 配置 : unknown entry 'access.log'

MySQL Workbench 未通过 SSH 连接

php - 如何从表单中的空字段中获取空值?

php - 未定义类型 'Tymon\JwTAuth\Contracts\JWTSubject'

javascript - PHP使用复选框从数据表中删除多行

java - Android ArrayList<String[]> 到 PHP

php - 在模板的 Symfony 翻译中使用 Twig 变量

php - 如果只有一行,SQL 拒绝删除行