簡體   English   中英

CakePHP:無法通過belongsTo 關聯的子項將數據保存到父實體

[英]CakePHP: Unable to save data to parent entity via belongsTo associated child

問題描述

我正在嘗試配置 CakePHP 3.7 API 以以子級優先的方式保存關聯數據。 實體 - 例如,讓我們稱它們為UsersPersons - 它們的關系如下:

用戶表.php

...
  $this->belongsTo('Persons', [
    'foreignKey' => 'person_id',
    'joinType' => 'LEFT',
    'className' => 'MyPlugin.Persons',
  ]);
...

人員表.php

  $this->hasOne('Users', [
    'foreignKey' => 'person_id',
    'className' => 'MyPlugin.Users'
  ]);

在它們各自的實體中,它們各自將彼此的屬性可見性設置為true 我想要做的是POST/users/路由( UsersController.php )並讓它也保存包含的Persons對象。 有效載荷是這樣的:

{
    "username": "foo",
    "password": "bar",
    "persons": {
        "dob": "1982-07-03",
    }
}

保存方法的相關部分如下,來自UsersController.php

  if ($this->request->is('post') && !empty($this->request->getData())) {
    $data = $this->request->getData();
    $newEntity = $this->Users->newEntity($data, ['associated' => 'Persons']);

    $savedEntity =  $this->Users->save($newEntity);
  ...

錯誤

這會產生以下 SQL 錯誤。

PDOException:SQLSTATE[23502]:非空沖突:7 錯誤:“person_id”列中的空值違反非空約束詳細信息:失敗的行包含(1,空,foo,bar)

我明白這是因為 Cake 試圖在沒有person_id來滿足外鍵約束的情況下保存給Users 不可能在我的應用程序域中反轉這種 FK 關系,因為我們需要向左的一對多關系(用戶 -> 1 人)。

我懷疑在JSON有效負載的persons對象中發送一個id將允許正確保存。 但是,由於各種原因,這在運行時是不可能的。 例如,這就是它在“保存數據”CakePHP 書籍頁面中的顯示方式......

$data = [
  'title' => 'First Post',
  'user' => [
      'id' => 1,
      'username' => 'mark'
  ]
];

...
$article = $articles->newEntity($data, [
    'associated' => ['Users']
]);

$articles->save($article);

我知道以下內容也可能按照xPfqHZ 的建議對類似問題起作用,因為Persons可以保存給Users ,但與我正在嘗試做的事情相比感覺不太合適,並且感覺好像有一種通過關聯的方法關於Users

  if ($this->request->is('post') && !empty($this->request->getData())) {
    $data = $this->request->getData();
    $newEntity = $this->Users->Persons->newEntity($data, ['associated' => 'Persons']);

    $savedEntity =  $this->Users->Persons->save($newEntity);
  ...

作品

現在我相信這在 CakePHP 2.X 中曾經是可能的,正如ndm在一個類似問題的答案中所述,其中一個人試圖通過hasOne實體在一個請求中保存belongsTo關聯實體及其父belongsTo實體。

這是預期的行為,saveAssociated() 不是只保存關聯的記錄,它也會保存主記錄,所以你應該只使用 saveAssociated(),不需要手動設置外鍵等,CakePHP 會做那個自動。

控制器

public function create() { if ($this->request->is('post') && !empty($this->request->data)): $this->CandidatesProblemReport->create(); if ($this->CandidatesProblemReport->saveAssociated($this->request->data)): // ... endif; endif; }

但是,在saveAssociated() ,我無法在Users實體繼承的Cake\\ORM\\Table對象上找到或使用saveAssociated()方法。 調用它會產生一個方法未找到錯誤。 這個方法似乎只存在於Cake\\ORM\\Association對象上,詳見文檔 除非我遺漏了顯而易見的東西,否則有沒有辦法使用它,或者BelongsTo()及其兄弟方法在內部使用它嗎?

記錄/轉儲實體

使用Cake\\Log\\Log::error($newEntity); die(var_dump($newEntity)); 顯示了與對象水合的有效負載的Users數據,但我沒有看到附加的Persons對象(見下文)。

object(MyPlugin\Model\Entity\User)[299]
  public 'username' => string 'foo' (length=3)
  public 'password' => string 'bar' (length=3)
  public '[new]' => boolean true
  public '[accessible]' => 
    array (size=5)
      '*' => boolean false
      'person_id' => boolean true
      'username' => boolean true
      'password' => boolean true
      'person' => boolean true
  public '[dirty]' => 
    array (size=2)
      'username' => boolean true
      'password' => boolean true
  public '[original]' => 
    array (size=0)
      empty
  public '[virtual]' => 
    array (size=0)
      empty
  public '[hasErrors]' => boolean false
  public '[errors]' => 
    array (size=0)
      empty
  public '[invalid]' => 
    array (size=0)
      empty
  public '[repository]' => string 'MyPlugin.Users' (length=17) 

試圖\\Cake\\Log\\Log::error($savedEntity); 日志文件中不顯示任何內容。

save()關聯參數

我考慮的另一個解決方案是使用save()$options['associated] ,如文檔中所示(摘錄如下)。 如下設置為true,錯誤仍然發生。

保存( Cake\\Datasource\\EntityInterface $entity ,數組 $options [] )

...關聯:如果為真,它將保存在傳遞的 $entity 中找到的第一級關聯實體,只要為關聯定義的屬性被標記為臟。 如果是數組,它將被解釋為要保存的關聯列表。 通過將自定義選項設為數組值,可以使用此鍵提供用於保存關聯表對象的不同選項。 如果為 false,則不會保存關聯的記錄。 (默認值:真)...

UsersController.php :

  if ($this->request->is('post') && !empty($this->request->getData())) {
    $data = $this->request->getData();
    $newEntity = $this->Users->newEntity($data, ['associated' => 'Persons']);

    $savedEntity =  $this->Users->save($newEntity, ['associated' => true]);
  ...

概括

沒有通過PersonsController.php並利用其hasOne關系,我不太幸運地通過UsersController.php保存我的UsersPersons數據。

如果我遺漏了任何重要信息,或者您有任何疑問/需要更多信息,請提問! 我可能錯過了一些明顯的東西,但我很感激任何可能的建議/解決方案。

正如@ndm 所指出的,錯誤在於發布的數據。 根據文檔的“保存數據:保存 BelongsTo 關聯”頁面:

當保存belongsTo 關聯時,ORM 需要一個單一的嵌套實體,以關聯名稱的單數下划線版本命名。

張貼的關鍵persons應該是person 同樣,如果實體被命名為PersonSnapshots ,則與實體水合的有效載荷中的相關鍵需要是person_snapshot

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM