CakePHP2で複数のテーブルをJoinしてデータを取得・更新する際の基本

##美しくないjoin

Cookbookより：
テーブルを結合するには、Model::find() の 「モダン」 な構文を使います。

CakePHP2さんの主張するモダン

```php5
$options['joins'] = array(
    array('table' => 'channels',
        'alias' => 'Channel',
        'type' => 'LEFT',
        'conditions' => array(
            'Channel.id = Item.channel_id',
        )
    )
);

$Item->find('all', $options);
```

URL:
https://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html#joining-tables
SQLに恨みでもあるのかもしれないけど、SQLのjoinほうがずっと美しいと思います。

調べてみるとjoinしなくてもテーブルを結合できるみたいなので、そのの方法を記載します。関係ないですがCakeをCookするってどこか和みます。




##joinを使わない方法
ベースにする処理
Cookbookの入門プログラム
URL:https://book.cakephp.org/2.0/ja/getting-started.html

ブログの記事（Post）を登録するプログラムに、執筆者（User）を追加します。
執筆者（User）とブログの記事（Post）は１対Nの関係です。


###テーブル定義

usersテーブル作成

```sql
SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `users` (`id`, `username`, `password`, `created`, `modified`) VALUES
(1,	'user1',	'pass',	'2018-05-09 19:19:07',	'2018-05-09 19:19:07'),
(2,	'user2',	'pass2',	'2018-05-09 19:19:26',	'2018-05-09 19:19:26');
```

postsテーブル変更
テーブルusersの主キーidを外部制約にもつ項目、user_idを追加します。

```sql
ALTER TABLE `posts`
ADD `user_id` int(10) unsigned NULL AFTER `id`,
ADD FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);
```


###Model

Post.php
PostにbelongsToを追加します。

```php5
<?php
  class Post extends AppModel {
    public $belongsTo = 'User';
  }
?>
```


User.php
UserにhasManyを設定します。

```php5
<?php
  class User extends AppModel {
    public $hasMany = array(
        'Post' => array(
            'className' => 'Post'
        )
    );
  }
?>
```


###View

edit.php
変更用のviewにuser_idの項目を追加します。

```php5
<!-- File: /app/View/Posts/edit.ctp -->

<h1>Edit Post</h1>
<?php
echo $this->Form->create('Post');

//add start
echo $this->Form->input('user_id', array('label' => 'UserId'));
//add end

echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('Save Post');
?>
```



###Controller
function editにuser_idの取得処理を追加します。

```php5
    public function edit($id = null) {
      if (!$id) {
          throw new NotFoundException(__('Invalid post'));
      }

      $post = $this->Post->findById($id);

      //add start
      //Userテーブルからのデータ取得処理
      $this->set('users', $this->Post->User->find('list'));
      //add end
      
      （略）
```



##変更後の画面
![cake2.JPG](https://qiita-image-store.s3.amazonaws.com/0/255878/62a3650f-9bbb-6245-85b1-94ab30da9070.jpeg)




##参考にした記事

Qiita
CakePHP 1.x/2.x でJOINを超簡単に書く方法
URL:https://qiita.com/mpyw/items/a0e7b99a8582195f0108

Cookbook

```
belongsTo や hasOne 関係を使うケースで select 項目を生成したい場合、
 Users コントローラーに以下のコードを追加します
（User は Group に belongsTo していると仮定しています）:
```

URL:https://book.cakephp.org/2.0/ja/core-libraries/helpers/form.html#automagic-form-elements


##追記
編集画面でユーザーidに紐づく値（名前）を表示する場合には、Controllerの以下の部分を変更します。

```php5
    public function edit($id = null) {
      if (!$id) {
          throw new NotFoundException(__('Invalid post'));
      }

      $post = $this->Post->findById($id);

      //add start
      //Userテーブルからのデータ取得処理
      //idを表示する
      //$this->set('users', $this->Post->User->find('list'));
      //idに紐づく値（名前）を表示する
      $this->set('users', $this->Post->User->find('list',array('fields' => array('User.username'))));
      //add end

      （略）
```

###変更結果
![change.JPG](https://qiita-image-store.s3.amazonaws.com/0/255878/44de4b86-61fa-68d1-d5d3-e01e682a09ca.jpeg)


###参考にした記事
Cookbook
URL:https://book.cakephp.org/2.0/ja/models/retrieving-your-data.html#find-list