8
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-05-09

##美しくないjoin

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

CakePHP2さんの主張するモダン

$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)は1対Nの関係です。

###テーブル定義

usersテーブル作成

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を追加します。

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を追加します。

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

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

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

###View

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

<!-- 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の取得処理を追加します。

    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

##参考にした記事

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の以下の部分を変更します。

    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

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

8
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?