2014-12-10 3 views
3

Я проблемы при сохранении данных с hasMany ассоциацииCakePHP 3,0 Невозможно сохранить hasMany связанные данные

Это мой стол

1) после таблицы: каждый элемент имеет уникальный идентификатор.

id | title | ... 
1 | Aloha | ... 

2) стол изображения

id | post_id | image | ... 
1 | 1  | abc.jpg | ... 
2 | 1  | efg.jpg | ... 

Моя модель (таблица)

Сообщений Модель

// PostsTable.php 
<?php 

namespace App\Model\Table; 

use Cake\ORM\Query; 
use Cake\ORM\Table; 
use Cake\Validation\Validator; 

class PostsTable extends Table { 
    public function initialize(array $config) { 
     $this->table('posts'); 
     $this->displayField('title'); 
     $this->primaryKey('id'); 
     $this->addBehavior('Timestamp'); 
     $this->hasMany('Images', [ 
      'foreignKey' => 'id' 
     ]); 
    } 
} 

... 

Изображения Модель

// ImagesTable.php 
<?php 

namespace App\Model\Table; 

use Cake\ORM\Query; 
use Cake\ORM\Table; 
use Cake\Validation\Validator; 

class ImagesTable extends Table { 
    public function initialize(array $config) { 
     $this->table('images'); 
     $this->displayField('id'); 
     $this->primaryKey('id'); 
     $this->addBehavior('Timestamp'); 
     $this->belongsTo('Posts'); 
    } 
} 

... 

Мой контроллер

// PostsController.php 
... 
public function add() { 
    $post = $this->Posts->newEntity($this->request->data, [ 
     'associated' => ['Images'] 
    ]); 

    if ($this->request->is('post')) { 
     if ($this->Posts->save($post, ['associated' => ['Images']])) { 
      $this->Flash->success('The post has been saved.'); 
      return $this->redirect(['action' => 'index']); 
     } else { 
      $this->Flash->error('The post could not be saved. Please, try again.'); 
     } 
    } 

    $this->set('post', $post); 
} 

... 

Мой шаблон

// add.ctp 
<?= $this->Form->create($post); ?> 

<?php echo $this->Form->input('title'); ?> 

<?php echo $this->Form->input('images.0.image'); ?> 
<?php echo $this->Form->input('images.1.image'); ?> 
<?php echo $this->Form->input('images.2.image'); ?> 

<?= $this->Form->button(__('Submit'), ['class' => 'button-green']) ?> 

<?= $this->Form->end() ?> 

Входной результат массива Debug

[ 
    'title' => 'Hello', 
    'images' => [ 
     (int) 0 => [ 
      'image' => 'testa.jpeg' 
     ], 
     (int) 1 => [ 
      'image' => 'testb.jpeg' 
     ], 
     (int) 2 => [ 
      'image' => 'testc.jpeg' 
     ] 
    ] 
] 

(Update) отладки ($ пост)

object(App\Model\Entity\Story) { 

    'new' => true, 
    'accessible' => [ 
     'title' => true, 
     'images' => true 
    ], 
    'properties' => [ 
     'title' => 'Hello', 
     'images' => [ 
      (int) 0 => object(App\Model\Entity\Image) { 

       'new' => true, 
       'accessible' => [ 
        'post_id' => true, 
        'image' => true, 
        'post' => true 
       ], 
       'properties' => [ 
        'image' => 'testa.jpeg' 
       ], 
       'dirty' => [ 
        'image' => true 
       ], 
       'original' => [], 
       'virtual' => [], 
       'errors' => [], 
       'repository' => 'Images' 

      }, 
      (int) 1 => object(App\Model\Entity\Image) { 

       'new' => true, 
       'accessible' => [ 
        'post_id' => true, 
        'image' => true, 
        'post' => true 
       ], 
       'properties' => [ 
        'image' => 'testb.jpeg' 
       ], 
       'dirty' => [ 
        'image' => true 
       ], 
       'original' => [], 
       'virtual' => [], 
       'errors' => [], 
       'repository' => 'Images' 

      }, 
      (int) 2 => object(App\Model\Entity\Image) { 

       'new' => true, 
       'accessible' => [ 
        'post_id' => true, 
        'image' => true, 
        'post' => true 
       ], 
       'properties' => [ 
        'image' => 'testc.jpeg' 
       ], 
       'dirty' => [ 
        'image' => true 
       ], 
       'original' => [], 
       'virtual' => [], 
       'errors' => [], 
       'repository' => 'Images' 

      } 
     ] 
    ], 
    'dirty' => [ 
     'title' => true, 
     'images' => true 
    ], 
    'original' => [], 
    'virtual' => [], 
    'errors' => [], 
    'repository' => 'Stories' 

} 

Я не могу понять, что я делаю неправильно

Спасибо

+0

"_can't save ..._" означает, что именно? Также что делает 'debug ($ post);' show? – ndm

+0

@ndm I означает значение $ this-> Post-> save ($ post, ['associated' => 'Images']) всегда возвращает false. Я обновил свой вопрос и показал результат отладки ($ post) – rslhdyt

+0

Ну, сущность выглядит хорошо, как она выглядит после сохранения? Есть ли ошибки? – ndm

ответ

1

попробовать это:

<?php echo $this->Form->input('0.Images.image'); ?> 
<?php echo $this->Form->input('1.images.image'); ?> 
<?php echo $this->Form->input('2.images.image'); ?> 

с междунарами до, в соответствии с http://book.cakephp.org/3.0/en/views/helpers/form.html#field-naming-conventions

+0

Ответы не должны быть только кодом, вы должны уметь объяснить, почему/как это могло бы решить проблему (что, скорее всего, не так, поскольку строчные буквы верны, если только имя свойства ** ** (http: // book.cakephp.org/3.0/en/orm/associations.html) настраивается). – ndm

+0

Это, по-видимому, ошибка в документе, согласно http://book.cakephp.org/3.0/en/views/helpers/form.html#associated-form-inputs – Will

2

Я не смотрел все, но я видел, есть ошибка в вашем заявлении ассоциации:

$this->hasMany('Images', [ 
    'foreignKey' => 'id' 
]); 

Документы например:

foreignKey: имя внешнего ключа найдено в другой модели. Это особенно удобно, если вам нужно определить несколько отношений hasMany. Значением по умолчанию для этого ключа является подчеркнутое, уникальное имя фактической модели с суффиксом '_id'.

Так оно и должно быть:

$this->hasMany('Images', [ 
    'foreignKey' => 'post_id' 
]); 

или даже:

$this->hasMany('Images'); 
1

Я только что закончил свой 3-часовой тур с сохранением содержания hasMany наряду с основной моделью. Эта борьба, кажется, еще хуже, если рассмотреть возможность сохранения многих объектов основной модели со многими связанными элементами.

  1. Внешний ключ в hasMany отношениях является сингулярным именем текущей модели (объект) с суффиксом _ID, так как:

    class MainModel extends Table { 
    ... 
    public function initialize(array $config) { 
    ... 
    // remember the "s" at the end of the name 
    $this->hasMany('VeryWeirdCalleds', [ 
         'className' => 'VeryWeirdCalleds', 
         'foreignKey' => 'main_model_id', 
         'propertyName' => 'very_weird_calleds' 
        ]); 
    ... 
    } 
    ... 
    } 
    

Затем установить доступный в главном Entity, так что ГЛАВНОЕ модель может сохранить ассоциации на основе индекса «very_weird_calleds»:

class MainModel extends Entity { 
    protected $_accessible = [ 
     ... 
     'very_weird_calleds' => true, 
    ]; 
} 

И последнее (BU t не менее): сохранение контроллера. Это, как правило, самая трудная часть, чтобы преодолеть, из-за того, что документы не проясняют весь процесс в деталях:

class MainModelsController extends AppController { 

public function add($data) { 
     $data = [ 
      [ 
       'name' => 'Hello', 
       'body' => 'Bla bla', 
       'very_weird_calleds' => [ 
        [ 
         'name' => 'Very Weird Called' 
        ] 
       ] 
      ] 
     ]; 
     foreach ($data as $record) { 
      $main = $this->MainModels->newEntity($record); 

      if(isset($record['images']) && !empty($record['images'])) { 
       foreach($record['images'] as $record_image) { 
        $image = $this->MainModels->VeryWeirdCalleds->newEntity(); 
        $image->IMAGE = $record_image['IMAGE']; 
        $import->very_weird_calleds[] = $image; 
       } 
      } 
      if (!$this->MainModels->save($main)) { 
       $this->Flash->error('The main model could not be saved. Please, try again.'); 
      } 
     } 
    } 

Объяснение? Прежде всего, мы в цикле данных, предварительно подготовленных следующим образом:

[ 'главной', 'модель', 'данные', 'association_accessible_property' => [ 'associated_data']]]

Тогда мы создайте новые записи для связанных данных, используя тот же метод, что и для основной модели. Последнее состоит в том, чтобы добавить связанные объекты к основной модели Entity.

Обратите особое внимание на имена, приведенные в этом примере. «S'-es» и «CamelCases» не являются случайными.

Смежные вопросы