У меня есть таблица, в которой есть несколько ссылок на таблицы ohter, например
user id name email categories id title user_categories user_id category_id
Здесь у пользователя будет несколько категорий, связанных с ним
Я могу успешно сохранить эти новые записи, например, следующие
Посмотреть файл:
echo $form->field($package_categories, 'category_id')->dropDownList( ArrayHelper::map( StudyMaterialCategories::find()->all(), 'id', 'title'), ['multiple' => true] );
Сохранить новую запись:
$model = new Packages(); $package_categories = new PackageCategories(); $request = Yii::$app->request; if ($request->isPost) { $transaction = Yii::$app->db->beginTransaction(); try { $post = $request->post(); $model->load($post); $model->save(); foreach ($post['PackageCategories']['category_id'] as $key => $value) { $package_categories = new PackageCategories(); $package_categories->category_id = $value; $package_categories->package_id = $model->id; $package_categories->save(); } $transaction->commit(); return $this->redirect(['view', 'id' => $model->id]); } catch (Exception $ex) { $transaction->rolback(); Yii::$app->session->setFlash("error", $ex->getMessage()); } }
До сих пор он работает успешно.
Но я застрял, когда собираюсь обновить таблицу. Проблема состоит в выпадающем списке. Как установить несколько выбранных параметров в соответствии с базой данных, если я прихожу с массивом объекта. Посмотрите следующий код
$package_categories = PackageCategories::find() ->where('package_id=:package_id', ['package_id' => $id])->all(); if (count($package_categories) < 1) { $package_categories = new PackageCategories(); } $request = Yii::$app->request; if ($request->isPost) { $transaction = Yii::$app->db->beginTransaction(); try { $post = $request->post(); $model->load($post); $model->save(); $package_categories = new PackageCategories(); $package_categories->deleteAll( "package_id=:package_id", [':package_id' => $model->id] ); foreach ($post['PackageCategories']['category_id'] as $key => $value) { $package_categories = new PackageCategories(); $package_categories->category_id = $value; $package_categories->package_id = $model->id; $package_categories->save(); } $transaction->commit(); return $this->redirect(['view', 'id' => $model->id]); } catch (Exception $ex) { $transaction->rolback(); Yii::$app->session->setFlash("error", $ex->getMessage()); } }
если я попытаюсь получить первый объект массива $package_categories
сможет установить только один вариант
Это пример кода Permit
класса модели, который имеет many to many
отношений с Activity
через PermitActivity
(модель сводной таблицы).
Активность класса модели
public class Permit extends \yii\db\ActiveRecord { public $activities_ids; ... public function rules() { return [ ... [['activities_ids'], 'safe'], ... ]; } ... // Method called after record is saved, be it insert or update. public function afterSave($insert, $changedAttributes) { // If this is not a new record, unlink all records related through relationship 'activities' if(!$this->isNewRecord) { // We unlink all related records from the 'activities' relationship. $this->unlinkAll('activities', true); // NOTE: because this is a many to many relationship, we send 'true' as second parameter // so the records in the pivot table are deleted. However on a one to many relationship // if we send true, this method will delete the records on the related table. Because of this, // send false on one to many relationships if you don't want the related records deleted. } foreach($this->activities_ids as $activity_id) { // Find and link every model from the array of ids we got from the user. $activity = Activity::findOne($activity_id); $this->link('activities', $activity); } parent::afterSave($insert, $changedAttributes); } ... // Declare relationship with Activity through the pivot table permitActivity public function getActivities(){ return $this->hasMany(Activitiy::className(), ['id' => 'activity_id']) ->viaTable('permitActivity',['permit_id' => 'id']); } ... public function afterFind(){ parent::afterFind(); $this->activities_id = ArrayHelper::getColumn($this->activities, 'id'); } }
Таким образом, класс модели является ответственным за создание и обновление отношений с использованием сводной таблицы.
Самое главное – правильно определить метод отношений.
редактировать
Это пример представления с использованием kartikv\widgets\Select2
. Я действительно не знаю, поддерживает ли dropDownList множественный выбор, однако в Select2 есть так много полезных функций, которые я обычно использую для других опций.
echo $form->field($model, 'activities')->widget(Select2::classname(), [ 'data' => $data, 'options' => [ 'placeholder' => '...' ], 'pluginOptions' => [ 'allowClear' => true, 'multiple' => true, ], ]);