Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What is going on with this article?
@uneri

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

More than 3 years have passed since last update.

美しくない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

9
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
uneri

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
9
Help us understand the problem. What is going on with this article?