Литий: как отображать связанные данные в формах, а затем сохранять их?

Я использую Lithium с MySQL. У меня есть модель Users, которая hasOne Contacts. Модель контактов belongsTo Пользователи.

Я перечислил очень простую версию моего кода ниже.

Мои вопросы:

  1. Когда я редактирую пользователя и отправляю форму, как сделать, чтобы Users::edit также сохранял контактные данные?
  2. Кроме того, как отобразить contact.email в режиме редактирования пользователей?

модели/Пользователи.php

<?php
namespace app\models;

class Users extends \lithium\data\Model {

    public $hasOne = array('Contacts');

    protected $_schema = array(
        'id'   => array('type' => 'integer',
                        'key'  => 'primary'),
        'name' => array('type' => 'varchar')
    );
}
?>

модели/Контакты.php

<?php
namespace app\models;

class Contacts extends \lithium\data\Model {

    public $belongsTo = array('Users');

    protected $_meta = array(
        'key'   => 'user_id',
    );

    protected $_schema = array(
        'user_id' => array('type' => 'integer',
                           'key'  => 'primary'),
        'email'   => array('type' => 'string')
    );
}
?>

контроллеры/UsersController.php

<?php
namespace app\controllers;

use app\models\Users;

class UsersController extends \lithium\action\Controller {
    public function edit() {
        $user = Users::find('first', array(
                'conditions' => array('id' => $this->request->id),
                'with'       => array('Contacts')
            )
        );

        if (!empty($this->request->data)) {
            if ($user->save($this->request->data)) {
                //flash success message goes here
                return $this->redirect(array('Users::view', 'args' => array($user->id)));
            } else {
                //flash failure message goes here
            }
        }
        return compact('user');
    }
}
?>

просмотры/пользователи/edit.html.php

<?php $this->title('Editing User'); ?>
<h2>Editing User</h2>
<?= $this->form->create($user); ?>
    <?= $this->form->field('name'); ?>
    <?= $this->form->field('email', array('type' => 'email')); ?>
<?= $this->form->end(); ?>

person Housni    schedule 15.02.2012    source источник


Ответы (1)


Не многие знают об этом, но с литием вы можете привязать форму к нескольким объектам.

В вашем контроллере верните и пользователя, и контактный объект. Затем в вашей форме:

<?= $this->form->create(compact('user', 'contact')); ?>

Затем вы визуализируете поле из определенного объекта следующим образом:

<?= $this->form->field('user.name'); ?>
<?= $this->form->field('contact.email'); ?>

Когда пользователь отправляет форму, данные для обоих объектов будут сохранены как:

$this->request->data['user'];
$this->request->data['contact'];

Вы можете использовать эту информацию для обновления базы данных, как обычно. Если вы хотите сохранить информацию только в том случае, если данные обоих объектов действительны, вы можете вызвать проверку следующим образом:

$user = Users::create($this->request->data['user']);
if($user->validates()) {
    $userValid = true;
}

$contact = Contacts::create($this->request->data['contact']);
if($contact->validates()) {
    $contactValid = true;
}

if($userValid && $userValid){
    // save both objects
}

Надеюсь, это поможет :)

person Max Mumford    schedule 19.05.2013
comment
Только что увидел дату по этому вопросу ... ну что ж, однажды это может кому-нибудь помочь! - person Max Mumford; 19.05.2013
comment
Спасибо, Макс. Очень мило, что так подробно ответили :) - person Housni; 02.06.2013
comment
Нет проблем, хорошо иметь возможность что-то вернуть переполнению стека!! :) - person Max Mumford; 09.06.2013