質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

3回答

3034閲覧

【CakePHP,MySQL】アソシエーションしたモデルの取得件数制限

ichinohetomo

総合スコア27

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

1クリップ

投稿2015/06/27 06:53

編集2015/06/27 06:59

UserモデルとMessageモデルを結合してリストを取得した時に、ユーザーの最新のメッセージ1件のみに制限してViewにリストを渡したいです。

Modelは他のViewで一覧取得しているため、Modelのconditionで取得メッセージの制限はしたくありません。

そのためコントローラの処理で件数を制限して取得したいです。

UsersController.php

lang

1 public function find_user(){ 2 $message = null; 3 $result = false; 4 if($this->request->is('post')) { 5 if(!empty($this->request->data['User']['word'])){ 6 $findListName = null; 7 $this->set('findWord',$this->request->data['User']['word']); 8 9 $findWord = '%'.$this->request->data['User']['word'].'%'; 10 $findListName = $this->User->find('list',array( 11 'conditions' => array('OR' => array( 12 'User.username LIKE' => $findWord, 13 'User.name LIKE' => $findWord)), 14 'fields' => array('User.id') 15 16 )); 17 18 $this->set('resultList',$this->User->find('all',array( 19 'conditions' => array('AND' => array( 20 'User.id' => $findListName)), 21 'Message' => array('limit' => 1) 22 23 ))); 24 $message = '検索結果を表示します。' ; 25 return $this->render('find_user_result'); 26 //return(処理をここで終わらせる)render(処理を元の処理ではなく、値のURLに飛ばす。 27 } else { 28 $message = '検索ワードを入力してください。'; 29 } 30 } 31 $this->Session->setFlash($message); 32 } 33
$this->set('resultList',$this->User->find('all',array( 'conditions' => array('AND' => array( 'User.id' => $findListName)), 'Message' => array('limit' => 1)

上記の処理を実行すると、viewのdebug($resultList)では全件戻ってきます。

'Message' => array('limit' => 1)を
'limit' => array('Message' => 1)と入力すると下記のようにユーザー1件分しか戻ってきません。Messageは1件でユーザーリストは全件返したいです。

lang

1array( 2 (int) 0 => array( 3 'User' => array( 4 'password' => '*****', 5 'id' => '41', 6 'username' => 'satoshii', 7 'name' => 'さとし1', 8 'mail' => 'satoshi@gmail.com', 9 'hidden_flag' => false, 10 'created' => '2015-06-21 23:03:00' 11 ), 12 'Message' => array( 13 (int) 0 => array( 14 'id' => '24', 15 'u_id' => '41', 16 'murmur' => 'つぶやきuser41つぶやき2個', 17 'created' => '2015-06-18 18:12:00' 18 ), 19 (int) 1 => array( 20 'id' => '23', 21 'u_id' => '41', 22 'murmur' => 'つぶやきuser41つぶやき1個', 23 'created' => '2015-06-18 12:12:00' 24 ) 25 ) 26 ) 27)

ここの処理で、最新のメッセージ1件のみを取得する方法がいまいちわかりません。
ちなみにMessageモデルとUserモデルを連結した時にMessage.createdでDESCしているので、順序は最新のつぶやき順になっているので、頭の1件だけ取得するような処理であれば大丈夫なはずです。

一応ですが、下記がモデルになります。

lang

1App::uses('AppModel', 'Model'); 2 3class Message extends AppModel { 4 5 public $name = 'Message'; 6 public $primaryKey = 'id'; 7 public $belongsTo = array( 8 'User' => array( 9 'className' => 'User', 10 'foreignKey' => 'u_id', 11 'order' => 'Message.created DESC' 12 )); 13}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

大変申し訳ございませんでした。そもそも掲示したmodelがMessageモデルで一覧取得に使っているモデルで、勘違いで載せてしまいました。後から見直したところ、検索で使用しているモデルはUserモデルで下記の通り、一行'limit' => 1 を追加して解決しました。

勘違いで申し訳ございません。

DaisukeKawabata様

bindModelというのがあるのですね。大変勉強になりました。
今回は私の質問が間違っていましたが、今回の方法に合致する方法で具体的だったのでベストアンサーとさせて頂きました。ありがとうございました。

takayukiinaba様

ご回答ありがとうございました。

lang

1<?php 2App::uses('AppModel', 'Model'); 3 4class User extends AppModel { 5 6 public $name = 'User'; 7 public $primaryKey = 'id'; 8 public $hasMany = array( 9 'Message' => array( 10 // 11 'className' => 'Message', 12 'foreignKey' => 'u_id', 13 'order' => 'Message.created DESC', 14 'limit' => '1' 15 )); 16 17 18 //入力チェック機能 19 public $validate = array( 20 'username' => array( 21 array( 22 'rule' => 'isUnique', //重複禁止 23 'message' => '既に使用されている名前です。' 24 ), 25 array( 26 'rule' => 'alphaNumeric', //半角英数字のみ 27 'message' => 'UserIDは半角英数字にしてください。' 28 ), 29 array( 30 'rule' => array('between', 2, 32), //2~32文字 31 'message' => 'UserIDは2文字以上32文字以内にしてください。' 32 ) 33 ), 34 'password' => array( 35 array( 36 'rule' => 'alphaNumeric', 37 'message' => 'パスワードは半角英数字にしてください。' 38 ), 39 array( 40 'rule' => array('between', 8, 32), 41 'message' => 'パスワードは8文字以上32文字以内にしてください。' 42 ) 43 ), 44 'mail' => array( 45 array( 46 'rule' => 'isUnique', 47 'message' => 'すでに登録されてあるメールアドレスです。' 48 ), 49 array( 50 'rule' => 'email', 51 'message' => 'メールアドレスの形式で入力してください。' 52 ) 53 ), 54 'name' => array( 55 array( 56 'rule' => 'notEmpty', 57 'message' => '他のユーザーに表示するお名前を入力してください。' 58 ) 59 ) 60); 61 62 public function beforeSave($options = array()) { 63 $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']); 64 return true; 65 } 66 67}

投稿2015/06/28 01:27

ichinohetomo

総合スコア27

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ぱっと見の思いつきなのでテストしてなくてごめんなさいなのですが。
Model上の(共通の)定義を変えたくないということであれば、下記のように、UserがhasManyしている関係を、Controller内でfindする直前に再定義してあげればいいのではないでしょうか?

lang

1$this->User->bindModel(array( 2 'hasMany' => array( 3 'Message' => array( 4 'className' => 'Message', 5 'foreignKey' => 'u_id', 6 'order' => 'Message.created DESC', 7 'limit' => 1 8 ) 9 )));

投稿2015/06/27 11:07

dk1987

総合スコア31

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dk1987

2015/06/27 12:13

$this->User->unbindModel する必要が有るかもしれないですね。
ichinohetomo

2015/06/28 01:28

掲示したModelが間違っておりました。大変申し訳ございませんでした。 教示して頂いた内容は大変ためになったので、ベストアンサーとさせて頂きました。 <(_ _)>
guest

0

こちらについてですが、そもそもテーブル構成上、UserテーブルとMessageテーブルの関係が1対Nの場合を考えると、その2テーブルを結合して取得する必要があるのでしょうか?
また、Messageテーブルで日付ソートを行っているので2テーブルを結合して取得する方法だと後々SQL実行時間が長くなるのではないかと思います。

私であれば、UserテーブルとMessageテーブルを別々で取得する方法を選択します。

また、一点気になったのですがMessageモデル内に、$belongsToで条件を設定しています。
こちらですが、モデル内ではなくコントローラ内で指定した方が汎用性があるのではないかと思います。

投稿2015/06/27 07:31

takayukiinaba

総合スコア1158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問