cakephp 3控制器操作->;如何使其智能化

cakephp 3控制器操作->;如何使其智能化,cakephp,cakephp-3.0,cakephp-3.1,Cakephp,Cakephp 3.0,Cakephp 3.1,我以可能最不公平的方式实现控制器操作。这怎么能变得更好呢?Table类与posterbin/cake bake类似。我认为创建实体的部分可以简化很多 我在做什么: 图书-->属于-->出版商出版编号 向数据库中添加书籍时,将从ISBN编号中提取publishernumber。然后,该编号以habtm关系链接到发布者。我需要它来建议用户在表单中键入isbn时使用一些出版商 代码暂时有效,但一年后,只有上帝知道我在这里做了什么。第一部分很简单 public function add() {

我以可能最不公平的方式实现控制器操作。这怎么能变得更好呢?Table类与poster
bin/cake bake
类似。我认为创建实体的部分可以简化很多

我在做什么: 图书-->属于-->出版商出版编号 向数据库中添加书籍时,将从ISBN编号中提取publishernumber。然后,该编号以habtm关系链接到发布者。我需要它来建议用户在表单中键入isbn时使用一些出版商

代码暂时有效,但一年后,只有上帝知道我在这里做了什么。第一部分很简单

public function add()
{
    $book = $this->Books->newEntity();
    $associations = ['associated' =>
            [   
                'Tags',
                'Publishers',
                'Publishers.Publishernumbers'
            ]
        ];
    if ($this->request->is('post')) {
        $data= $this->request->data;


        $publisher = $this->Books->Publishers->get(
            $this->request->data['publisher_id'], 
                ['contain' => ['Publishernumbers']]
        );
        unset($data['publisher_id']);

        $book->publisher = $publisher;

    //extract group- and publishernumber from the ISBN
    $this->loadComponent('Isbn.Isbn');
    $split = $this->Isbn->splitIsbn($this->request->data['isbn']);
    $publishernumber = $split[1].$split[2];
这就是混乱开始的地方。我认为这可以做得更优雅一些

    //check if the publisher contains already the $publishernumber
    //and if not, add it to the entity
    $new = true;
    foreach ($book->publisher->publishernumbers as $n){
        if ($n->number == $publishernumber){
            $new = false;
        }
    }
    if ($new){
        $existingNumber = $this->Books->Publishers->Publishernumbers
            ->findByNumber($publishernumber)
            ->first();
        if (!$existingNumber){

            //publishernumber does not exist in the database
            $pubnumber = $this->Books->Publishers->Publishernumbers
                ->newEntity();
            $pubnumber = $this->Books->Publishers->Publishernumbers
                ->patchEntity($pubnumber, ['number' => $publishernumber]);
            $book->publisher->publishernumbers[] = $pubnumber;

        } else {

            //publishernumber exists in the database 
            //but is not associated with the publisher
            $book->publisher->publishernumbers[] = $existingNumber;
        }
        $book->publisher->dirty('publishernumbers', true);
    }


    $book = $this->Books->patchEntity($book, $data, $associations);
拯救

    if ($this->Books->save($book, $associations)){
        Cache::delete('exlibrisBooksIndex');
        $this->Flash->success(__('The book has been saved.'));
        return $this->redirect(['action' => 'index']);
    } else {
        $this->Flash->error(__('Error.'));
    }
}
$publishers = $this->Books->Publishers->find('list')
    ->order('name')
    ->toArray();
$this->set(compact('book', 'publishers'));
$this->set('_serialize', ['book']);
}

清理控制器操作的第一步基本上是将所有代码放在一个表类方法中;无论保存记录的操作有多复杂,您的控制器代码应该看起来与烘焙输出几乎相同。我就是这么做的。控制器操作现在看起来像是烘焙的,所有附加逻辑现在都在publishersTable中。在书中称为afterSave methode。看起来更好,而且是可测试的!您应该添加更多关于您所做的事情的细节作为答案,并接受它的第一步,以清理控制器的操作基本上是将所有代码放在一个表类方法中;无论保存记录的操作有多复杂,您的控制器代码应该看起来与烘焙输出几乎相同。我就是这么做的。控制器操作现在看起来像是烘焙的,所有附加逻辑现在都在publishersTable中。在书中称为afterSave methode。看起来更好,而且是可测试的!你应该补充一点你所做的细节作为回答,并接受它