احفظ سجلات متعددة لنموذج واحد في CakePhP
-
27-09-2019 - |
سؤال
أود حفظ عدة سجلات لنموذج واحد. كان من الممكن القيام بذلك بسهولة مع saveAll()
إذا لم يكن الأمر لمشكلة:
لدي نموذج إشعار ، حيث أختار العديد من المستخدمين من أ <select>
وحقلان ، للموضوع والمحتوى على التوالي. الآن ، عندما أخرج ماذا $this->data
يحتوي ، لدي:
Array([Notification] => Array
(
[user_id] => Array
(
[0] => 4
[1] => 6
)
[subject] => subject
[content] => the-content-here
)
)
لقد قرأت كتاب Cake 1.3 ، من أجل حفظ سجلات متعددة لنموذج ، يجب أن يكون لديك $this->data
شيء مثل:
Array([Article] => Array(
[0] => Array
(
[title] => title 1
)
[1] => Array
(
[title] => title 2
)
)
)
لذا ، كيف يمكنني "مشاركة" الموضوع والمحتوى لجميع المستخدمين المحددين؟
المحلول
أولاً ، يجب تطبيع تصميم قاعدة البيانات هذا.
يبدو لي مثل أ Notification
يمكن أن يكون لديه الكثير User
S المتعلقة به. في الوقت نفسه ، أ User
يمكن أن يكون لديه الكثير Notification
س. وبالتالي،
- تقديم جدول انضمام يسمى users_notifications.
- تنفيذ علاقة HABTM: الإخطار Hasandbelongstomany المستعمل
في العرض ، يمكنك ببساطة استخدام الكود التالي لإظهار النموذج المتعدد بشكل تلقائي للاستيلاء على معرفات المستخدم:
echo $this->Form->input('User');
البيانات التي يتم إرسالها إلى وحدة التحكم ستكون من النموذج:
Array(
[Notification] => Array
(
[subject] => subject
[content] => contentcontentcontentcontentcontentcontent
),
[User] => Array
(
[User] => Array
(
[0] => 4
[1] => 6
)
)
)
الآن ، كل ما عليك فعله هو تسمى وظيفة Saveall () بدلاً من حفظ ().
$this->Notification->saveAll($this->data);
وهذه هي طريقة الكعكة للقيام بذلك!
نصائح أخرى
يجب أن تكرر هذه القيم مثل هذا
Array([Notification] => Array(
[0] => Array
(
[user_id] => 4
[subject] => subjects
[content] => content
)
[1] => Array
(
[user_id] => 6
[subject] => subject
[content] => contents
)
)
)
$this->Notification->saveAll($data['Notification']); // should work
إذا لم تقم بتمرير أي قيمة عمود ، فستتجاهلها هذه الكعكة
سيتعين عليك تدليك ناتج النموذج الخاص بك ليناسب Model::saveAll
. في وحدة التحكم الخاصة بك:
function action_name()
{
if ($this->data) {
if ($this->Notification->saveMany($this->data)) {
// success! :-)
} else {
// failure :-(
}
}
}
وفي النموذج الخاص بك:
function saveMany($data)
{
$saveable = array('Notification'=>array());
foreach ($data['Notification']['user_id'] as $user_id) {
$saveable['Notification'][] = Set::merge($data['Notification'], array('user_id' => $user_id));
}
return $this->saveAll($saveable);
}
الفائدة هنا هي أن وحدة التحكم الخاصة بك لا تزال لا تعرف شيئًا عن مخطط النموذج الخاص بك ، وهو ما لا ينبغي.
في الواقع ، ربما يمكنك إعادة تعريف saveAll
في النموذج الخاص بك ، الذي يسلط صفيفات الإدخال المنسقة بشكل صحيح إلى parent::saveAll
, ، ولكن يتعامل مع الحالات الخاصة نفسها.
قد تكون هناك طريقة أكثر كعكًا للقيام بذلك ، لكنني استخدمت هذا النوع من التقنية: أولاً ، قم بتغيير النموذج بحيث تحصل على صفيف مثل هذا:
Array(
[Notification] => Array
(
[subject] => subject
[content] => contentcontentcontentcontentcontentcontent
),
[selected_users] => Array
(
[id] => Array
(
[0] => 4
[1] => 6
)
)
)
(فقط قم بتغيير اسم المدخلات المتعددة إلى Selection_users.id)
ثم حلقة من خلال معرفات المستخدم وحفظ كل سجل بشكل فردي:
foreach( $this->data[ 'selected_users' ][ 'id' ] as $userId ) {
$this->data[ 'Notification' ][ 'user_id' ] = $userId;
$this->Notification->create(); // initializes a new instance
$this->Notification->save( $this->data );
}