[英]CakePHP: Unable to save data to parent entity via belongsTo associated child
我正在嘗試配置 CakePHP 3.7 API 以以子級優先的方式保存關聯數據。 實體 - 例如,讓我們稱它們為Users
和Persons
- 它們的關系如下:
用戶表.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
保存我的Users
和Persons
數據。
如果我遺漏了任何重要信息,或者您有任何疑問/需要更多信息,請提問! 我可能錯過了一些明顯的東西,但我很感激任何可能的建議/解決方案。
正如@ndm 所指出的,錯誤在於發布的數據。 根據文檔的“保存數據:保存 BelongsTo 關聯”頁面:
當保存belongsTo 關聯時,ORM 需要一個單一的嵌套實體,以關聯名稱的單數、下划線版本命名。
張貼的關鍵persons
應該是person
。 同樣,如果實體被命名為PersonSnapshots
,則與實體水合的有效載荷中的相關鍵需要是person_snapshot
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.