2016-10-10 3 views
0

У меня возникла проблема с попыткой получить данные, сохраненные в связанных таблицах (в настоящее время, когда я сохраняю их только в исходной таблице, но не в других).CakePHP 3.x - Сохранение связанных данных по нескольким таблицам

Так моя первая таблица (пользователей):

-id 
-username 
-password 
-email 

Второй стол (Artists):

-name 
-cp_id (foreign key) 
-user_id (foreign key) 
-genre 

Третий стол (Contactpersons):

-cp_firstname 
-cp_lastname 
-cp_email 
-cp_phoneno 

Отношения:

A User hasOne Artist. An Artist belongsTo a User. (1-1) 
An Artist belongsTo Contactperson. A Contactperson hasMany Artists (1 to many) 

user_id in Artists references id in Users 
cp_id in Artists references id in Contactpersons 

В моей UsersController:

public function artistregister() 
    { 
     $user = $this->Users->newEntity(); 
     if($this->request->is('post')){ 
      $data = $this->request->data; 
      $data['role_id'] = "2"; //role_id 2 makes the user register as role = artist 
      $user = $this->Users->patchEntity($user, $data); 
      $save = $this->Users->save($user); 
      if ($save) { 
      $user_id = $save->id; 
      $data['user_id'] = $user_id; 
      $ContactPersonsController = new ContactPersonsController(); 
      $ContactPersonsController->artistregister($data); 
      $ArtistController = new ArtistsController(); 
      $ArtistController->artistregister($data); 
      $this->Flash->success(__('Registration completed')); 
      return $this->redirect(['action' => 'login']); 
      } else { 
      $this->Flash->error(__('Registration failed. Please try again.')); 
      } 
     } 
     $artists = $this->Users->Artists->find('all'); 
     $persons = $this->Users->Artists->ContactPersons->find('all')->toArray(); 
     $this->set(compact('user', 'artists', 'roles', 'contactpersons','persons')); 
      $this->set('_serialize', ['user']); 
    } 

Затем в контроллере Contactpersons, ту же функцию:

public function artistregister($data) 
    { 
    if ($this->Contactpersons) 
     $contactperson = $this->Contactpersons->newEntity(); 
     $contactperson = $this->Contactpersons->patchEntity($contactperson, $data); 
     if ($this->Contactpersons->save($contactperson)) { 
      $this->Flash->error(__('Contact person details could not be saved. Please try again.')); 
     } 
     $this->set(compact('contactpersons')); 
     $this->set('_serialize', ['contactperson']); 
    } 

И ArtistsController, та же функция снова:

public function artistregister($data) 
    { 
     $artist = $this->Artists->newEntity(); 
    $user = $this->request->session()->read('Auth.User'); 
    $data['user_id'] = $user['id']; 
    $contactperson = $this->request->session()->read('Auth.Contactpersons') //I put in Auth.Contactpersons as a placeholder, but I'm not really sure what to put there. 
    $data['cp_id'] = $contactperson['id']; 
     $artist = $this->Artists->patchEntity($artist, $data); 
     if ($this->Artists->save($artist)) { 
      $this->Flash->error(__('Artist profile details could not be saved. Please try again.')); 
     } 
     $contactpersons = $this->Artists->Contactpersons->find('list', ['limit' => 200]); 
     $this->set(compact('artist', 'contactpersons')); 
     $this->set('_serialize', ['artist']); 
    } 

О и Хорошая мера, вот файл Artistregister.ctp:

<div class="container" style="margin-top: 70px;"> 
    <?= $this->Flash->render('auth') ?> 
    <?php $this->Form->templates([ 
     'inputContainer' => '<div class="form-group">{{content}}</div>', 
     'inputContainerError' => '<div class="error" style="color:red;">{{content}}{{error}}</div>' 
    ]);?> 
    <div class="col-sm-2"> 
    </div> 
    <div class="col-sm-8"> 
     <div class="container col-sm-12" style="border-radius: 10px; border: 1px solid;" > 
      <?= $this->Form->create($user, ['role'=>'form']) ?> 
      <header><?= __('Artist Registration') ?></header> 
      <legend><?= __('User Account Details') ?></legend> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('username', ['class'=>'form-control', 
       'placeholder'=>'Please enter a username.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('email', ['class'=>'form-control', 'type'=>'email', 
       'placeholder'=>'Please enter an email address.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('password', ['class'=>'form-control', 'type'=>'password', 
       'placeholder'=>'Please enter a password.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('confirm_password', array('type'=>'password', 
        'label'=>'Confirm Password', 'value'=>'', 'autocomplete'=>'off','class'=>'form-control', 
        'placeholder'=>'Please re-enter your password.'))?> 
      </div> 
      <legend><?= __('Artist Profile Details') ?></legend> 
      <div class="col-sm-12"> 
       <?= $this->Form->input('name', ['class'=>'form-control', 'label'=>'Artist Name', 
       'placeholder'=>'Please enter your artist name.']);?> 
      </div> 
      <div class="col-sm-12"> 
       <?= $this->Form->input('genre', ['class'=>'form-control', 'type'=>'textarea', 'label'=>'Genres', 
       'placeholder'=>'Please enter a description of the genres you play.']);?> 
      </div> 
      <legend><?= __('Contact Person Details') ?></legend> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('cp_firstname', ['class'=>'form-control', 'label'=>'First Name', 
       'placeholder'=>'Please enter the first name of your contact.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('cp_lastname', ['class'=>'form-control', 'label'=>'Last Name', 
       'placeholder'=>'Please enter the last name of your contact.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('cp_phoneno', ['class'=>'form-control','type'=>'tel', 'label'=>'Phone Number', 
       'placeholder'=>'Please enter the phone number of your contact.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('cp_email', ['class'=>'form-control','type'=>'email', 'label'=>'Email', 
       'placeholder'=>'Please enter the email of your contact.']);?> 
      </div> 
      <legend></legend> 
      <div class="col-sm-12" > 
       <?= $this->Form->button('<strong>'.__('Register').'</strong>', 
        ['class'=>'btn btn-primary', 'style'=>'width:100%;']); ?> 
      </div> 
      <div class="col-sm-12" align="center" style="margin-bottom: 20px;"> 
       <?= $this->Html->link(__("Already have an account? Log in"), ['action'=>'logout'])?> 
      </div> 
      <?= $this->Form->end() ?> 
     </div> 
    </div> 
    <div class="col-sm-2"> 
    </div> 
</div> 

Поэтому, когда я перехожу на страницу Artistregister, заполните поля и нажмите «Отправить», все данные, относящиеся к таблице «Пользователи», будут отправлены, но таблица «Контактные лица» и «Художники» остаются пустыми. В настоящее время ошибка, я получаю:

Call to undefined method App\Controller\ContactpersonsController::artistregister()

с линией ссылочного бытия:

$ContactPersonsController->artistregister($data); 

в UsersController.

Между тем, если я поменять порядок функций, вызываемых (т.е. вызов ArtistsController перед тем ContactpersonsController), я получаю эту ошибку:

syntax error, unexpected '$data' (T_VARIABLE)

с линией ссылочного бытия:

$data['cp_id'] = $contactperson['id']; 

Этот line находится в функции ArtistsController.

Я уверен, что получаю эту ошибку, потому что не существует контактного лица, поэтому он не может найти идентификатор, который нужно поставить как cp_id - вот почему в функции UserController я сначала вызывал ContactersonsController, чтобы установить некоторые данные в Таблица контактов.

Добавление в моделях для каждого:

Contactpersons:

class ContactpersonsTable extends Table 
{ 

    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->table('contactpersons'); 
     $this->displayField('id'); 
     $this->primaryKey('id'); 
    } 

    public function validationDefault(Validator $validator) 
    { 
     $validator 
      ->integer('id') 
      ->allowEmpty('id', 'create'); 

     $validator 
      ->requirePresence('cp_firstname', 'create') 
      ->notEmpty('cp_firstname'); 

     $validator 
      ->requirePresence('cp_lastname', 'create') 
      ->notEmpty('cp_lastname'); 

     $validator 
      ->requirePresence('cp_email', 'create') 
      ->notEmpty('cp_email'); 

     $validator 
      ->integer('cp_phoneno') 
      ->requirePresence('cp_phoneno', 'create') 
      ->notEmpty('cp_phoneno'); 

     return $validator; 
    } 
} 

Художники:

class ArtistsTable extends Table 
{ 

    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->table('artists'); 
     $this->displayField('name'); 
     $this->primaryKey('id'); 

     $this->addBehavior('Timestamp'); 

     $this->belongsTo('Contactpersons', [ 
      'foreignKey' => 'cp_id', 
      'joinType' => 'INNER' 
     ]); 
     $this->belongsTo('Users', [ 
      'foreignKey' => 'user_id', 
      'joinType' => 'INNER' 
     ]); 
     $this->hasMany('Bookings', [ 
      'foreignKey' => 'artist_id' 
     ]); 
    } 

    public function validationDefault(Validator $validator) 
    { 
     $validator 
      ->integer('id') 
      ->allowEmpty('id', 'create'); 

     $validator 
      ->requirePresence('name', 'create') 
      ->notEmpty('name'); 

     $validator 
      ->allowEmpty('genre'); 

     return $validator; 
    } 

    public function buildRules(RulesChecker $rules) 
    { 
     $rules->add($rules->existsIn(['cp_id'], 'Contactpersons')); 
     $rules->add($rules->existsIn(['user_id'], 'Users')); 

     return $rules; 
    } 
} 

пользователей:

class UsersTable extends Table 
{ 
    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->table('users'); 
     $this->displayField('id'); 
     $this->primaryKey('id'); 

     $this->addBehavior('Timestamp'); 

     $this->belongsTo('Roles', [ 
      'foreignKey' => 'role_id', 
      'joinType' => 'INNER' 
     ]); 

     $this->hasOne('Artists', [ 
       'foreignKey' => 'user_id' 
     ]); 

      $this->hasOne('Engineers', [ 
       'foreignKey' => 'user_id' 
     ]); 
    } 

    public function validationDefault(Validator $validator) 
    { 
     $validator 
      ->integer('id') 
      ->allowEmpty('id', 'create'); 

     $validator 
      ->requirePresence('username', 'create') 
      ->notEmpty('username'); 

     $validator 
      ->requirePresence('password', 'create') 
      ->notEmpty('password'); 

     $validator 
      ->email('email') 
      ->requirePresence('email', 'create') 
      ->notEmpty('email'); 

     return $validator; 
    } 

    public function buildRules(RulesChecker $rules) 
    { 
     $rules->add($rules->isUnique(['username'])); 
     $rules->add($rules->isUnique(['email'])); 
     $rules->add($rules->existsIn(['role_id'], 'Roles')); 

     return $rules; 
    } 
} 

ответ

0

Получил ответ - слегка измененный от того, что предусмотрено @Derek и с помощью от CakePHP Cookbook.

public function artistregister() 
    { 
     $user = $this->Users->newEntity($this->request->data(),[ 
      'associated'=>[ 
      'Artists' => ['associated' => ['Contactpersons']] 
      ] 
     ]); 
     if($this->request->is('post')){ 
      $data = $this->request->data; 
      $data['role_id'] = "2"; 
      $user = $this->Users->patchEntity($user, $data, [ 
      'associated'=>[ 
       'Artists' => ['associated' => ['Contactpersons']] 
      ] 
      ]); 
      $save = $this->Users->save($user); 
      $user_id = $save->id; 
      $data['user_id'] = $user_id; 
      $this->Flash->success(__('Registration completed')); 
      return $this->redirect(['action' => 'login']); 
     } else { 
      $this->Flash->error(__('Registration failed. Please try again.')); 
     } 
     $this->set(compact('user', 'artists', 'roles', 'contactpersons')); 
      $this->set('_serialize', ['user']); 
    } 
0

Изменить HTML на:

<div class="container" style="margin-top: 70px;"> 
    <?= $this->Flash->render('auth') ?> 
    <?php $this->Form->templates([ 
     'inputContainer' => '<div class="form-group">{{content}}</div>', 
     'inputContainerError' => '<div class="error" style="color:red;">{{content}}{{error}}</div>' 
    ]);?> 
    <div class="col-sm-2"> 
    </div> 
    <div class="col-sm-8"> 
     <div class="container col-sm-12" style="border-radius: 10px; border: 1px solid;" > 
      <?= $this->Form->create($user, ['role'=>'form']) ?> 
      <header><?= __('Artist Registration') ?></header> 
      <legend><?= __('User Account Details') ?></legend> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('username', ['class'=>'form-control', 
       'placeholder'=>'Please enter a username.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('email', ['class'=>'form-control', 'type'=>'email', 
       'placeholder'=>'Please enter an email address.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('password', ['class'=>'form-control', 'type'=>'password', 
       'placeholder'=>'Please enter a password.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('confirm_password', array('type'=>'password', 
        'label'=>'Confirm Password', 'value'=>'', 'autocomplete'=>'off','class'=>'form-control', 
        'placeholder'=>'Please re-enter your password.'))?> 
      </div> 
      <legend><?= __('Artist Profile Details') ?></legend> 
      <div class="col-sm-12"> 
       <?= $this->Form->input('artist.name', ['class'=>'form-control', 'label'=>'Artist Name', 
       'placeholder'=>'Please enter your artist name.']);?> 
      </div> 
      <div class="col-sm-12"> 
       <?= $this->Form->input('artist.genre', ['class'=>'form-control', 'type'=>'textarea', 'label'=>'Genres', 
       'placeholder'=>'Please enter a description of the genres you play.']);?> 
      </div> 
      <legend><?= __('Contact Person Details') ?></legend> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('contactperson.cp_firstname', ['class'=>'form-control', 'label'=>'First Name', 
       'placeholder'=>'Please enter the first name of your contact.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('contactperson.cp_lastname', ['class'=>'form-control', 'label'=>'Last Name', 
       'placeholder'=>'Please enter the last name of your contact.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('contactperson.cp_phoneno', ['class'=>'form-control','type'=>'tel', 'label'=>'Phone Number', 
       'placeholder'=>'Please enter the phone number of your contact.']);?> 
      </div> 
      <div class="col-sm-6"> 
       <?= $this->Form->input('contactperson.cp_email', ['class'=>'form-control','type'=>'email', 'label'=>'Email', 
       'placeholder'=>'Please enter the email of your contact.']);?> 
      </div> 
      <legend></legend> 
      <div class="col-sm-12" > 
       <?= $this->Form->button('<strong>'.__('Register').'</strong>', 
        ['class'=>'btn btn-primary', 'style'=>'width:100%;']); ?> 
      </div> 
      <div class="col-sm-12" align="center" style="margin-bottom: 20px;"> 
       <?= $this->Html->link(__("Already have an account? Log in"), ['action'=>'logout'])?> 
      </div> 
      <?= $this->Form->end() ?> 
     </div> 
    </div> 
    <div class="col-sm-2"> 
    </div> 
</div> 

Изменение UsersController на:

public function artistregister() 
{ 
    $user = $this->Users->newEntity(); 
    if($this->request->is('post')){ 
     $data = $this->request->data; 
     $data['role_id'] = "2"; //role_id 2 makes the user register as role = artist 
     $user = $this->Users->patchEntity($user, $data, ['associated' => ['ContactPersons', 'Artists']]); 
     $save = $this->Users->save($user); 
     if ($save) { 
      $this->Flash->success(__('Registration completed')); 
      return $this->redirect(['action' => 'login']); 
     } else { 
      $this->Flash->error(__('Registration failed. Please try again.')); 
     } 
    } 
    $artists = $this->Users->Artists->find('all'); 
    $persons = $this->Users->Artists->ContactPersons->find('all')->toArray(); 
    $this->set(compact('user', 'artists', 'roles', 'contactpersons','persons')); 
    $this->set('_serialize', ['user']); 
} 
+0

Я получаю эту ошибку сейчас, при этом данные не добавляются в таблицы, даже в таблице «Пользователи»: не удается вывести данные для ассоциации «ContactPersons». Он не связан с «Пользователями». InvalidArgumentException (как вы делаете новые строки в комментариях?) – mistaq

+0

опубликовать каждую из ваших моделей – Derek

+0

Добавлено в OP now – mistaq