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

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

解決済

2回答

2246閲覧

CakePHPのアソシエーション機能を使ってユーザー情報を分割したい

tacchan

総合スコア60

MySQL

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

CakePHP

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

0グッド

0クリップ

投稿2016/03/14 10:39

CakePHPのブログチュートリアルの延長で、一度記述したらあまり変更のないユーザー情報と頻繁に変更がある情報を分割しようと思い、アソシエーション機能で試行錯誤しているのですが上手くいきません。
イメージ説明
画像のAction部分の「追加」「削除」でユーザーのお気に入り記事のチェックを付けたり外したりできるようにしました。
「追加」のアクションchoice、「削除」のアクションnot_choiceのコードは以下の通りです。

PHP

1/app/Controller/PostsController.php 2class PostsController extends AppController { 3/// 4 5public function choice($id) { 6 if ($this->request->is('post')){ 7 $cond = $this->Auth->user('id'); 8 $user = $this->User->findByid($cond); 9 $data = $user['User']['choiced']; 10 $ch_spo = explode(',', $data); 11 $ch_spo = array_filter($ch_spo); 12 if(!in_array("$id", $ch_spo)){ 13 array_push($ch_spo, "$id"); 14 }; 15 $data = implode(',', $ch_spo); 16 $this->User->id = $this->Auth->user('id'); 17 $this->User->saveField('choiced', "$data"); 18 } 19 return $this->redirect(array('action' => 'index')); 20 } 21 22 public function not_choice($id) { 23 if ($this->request->is('post')){ 24 $cond = $this->Auth->user('id'); 25 $user = $this->User->findByid($cond); 26 $data = $user['User']['choiced']; 27 $ch_spo = explode(',', $data); 28 $ch_spo = array_filter($ch_spo); 29 if(in_array("$id", $ch_spo)){ 30 $del_id = array_search("$id", $ch_spo); 31 unset($ch_spo["$del_id"]); 32 }; 33 $data = implode(',', $ch_spo); 34 $this->User->id = $this->Auth->user('id'); 35 $this->User->saveField('choiced', "$data"); 36 } 37 return $this->redirect(array('action' => 'index')); 38 } 39}

結局何をしているかというと、記事のidをuserテーブルのchoicedカラムに保存しているだけです。

現在、choicedをuserテーブルと切り離し、新たにuser_detailテーブルに入れてこっちに書き込んでいこうとしているところです。
現在の一番の問題は、ユーザー登録した時点でuserテーブルだけでなくuser_detailテーブルにもレコードを作っておきたいのですが、出来ません。
userテーブルとuser_detailテーブルは以下の画像の通りです。
イメージ説明
イメージ説明
userが親でuser_detailが子のイメージだと思うのでuser_detail側にuser_idを入れています。
アソシエーションの設定を以下のようにしています。

php

1// app/Model/User.php 2class User extends AppModel { 3public $hasOne = 'User_detail'; 4} 5 6// app/Model/User_detail.php 7class User_detail extends AppModel { 8public $belongsTo = 'User'; 9}

外部キーは規約に沿っていると思うので、これだけでいいはずだと考えています。
会員登録時にuser_detailにもレコードの保存ができるようにするには、以下の会員登録ページのビューとアクションのコードをどのように変更すればいいのでしょうか?

PHP

1// app/Controller/UsersController.php 2class UsersController extends AppController { 3public function add() { 4 if ($this->request->is('post')) { 5 $this->User->create(); 6 if ($this->User->save($this->request->data)) { 7 $this->Flash->success(__('The user has been saved')); 8 return $this->redirect(array('action' => 'index')); 9 } 10 $this->Flash->error( 11 __('The user could not be saved. Please, try again.') 12 ); 13 } 14 } 15}

html

1<!-- app/View/Users/add.ctp --> 2<div class="users form"> 3<?php echo $this->Form->create('User'); ?> 4 <fieldset> 5 <legend><?php echo __('Add User'); ?></legend> 6 <?php echo $this->Form->input('username'); 7 echo $this->Form->input('password'); 8 echo $this->Form->input('role', array( 9 'options' => array('admin' => 'Admin', 'author' => 'Author') 10 )); 11 ?> 12 </fieldset> 13<?php echo $this->Form->end(__('Submit')); ?> 14</div>

複雑な説明になってわかりにくい説明になったかもしれませんが、出来るだけ詳しい説明をよろしくお願いします。

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

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

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

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

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

guest

回答2

0

自己解決

手っ取り早くapp/View/Users/add.ctp に
echo $this->Form->input('User_detail.choiced', array('type' => 'hidden', 'value' => ''));
を記述することによってUser_detailにもUserに対応するuser_idを持ったレコードを作ることができました。
しかし、なんか力技な感じがしているので、もっとスマートな方法があるという方がいらっしゃいましたら引き続き回答を募集しております。

投稿2016/03/14 15:09

tacchan

総合スコア60

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

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

shi_ue

2016/03/14 15:15

あ、空文字でもいいんですね。 力技ではなく正攻法だと思いますよ。
tacchan

2016/03/16 15:25

コメントありがとうございます。 正攻法と言っていただけて、うれしいです。 アドバイスを頂けてたどりつけました。 日にちを置いて他の回答を待ってみたのですが、もう来なさそうなので手前味噌ですが自分の方法をベストアンサーにさせていただきます。
guest

0

以下を参照して、アソシエーションごと保存してください。
http://book.cakephp.org/2.0/ja/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array

###追記
user_details.choicedにデータを入れてやらないから、レコードが作られないんじゃないですか?
でも、user_details.choicedはnull不可なので、user_details.choicedに入っていないという状態が作り出せません。

user_details.choicedのnullを可にしちゃダメですか?

そうしたら、

PHP

1$data = $this->request->data, 2$data['User_detail'] = ['checked'=>null]; 3$this->User->saveAssociated($data); 4```とかやると保存できそうですけど・・・ 5 6検証してませんけど。

投稿2016/03/14 11:12

編集2016/03/14 14:08
shi_ue

総合スコア4437

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

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

tacchan

2016/03/14 11:27

ありがとうございます。ただ、saveAssociatedは試してみたのですが上手くいきませんでした。 今回の場合、会員登録の時点でuser_detailにはレコードだけ(つまり場所だけ)保存して、何も保存するデータがないのですが、このような時はどうしたらいいのでしょうか? データ配列のuser_detailの部分は空ということです。
shi_ue

2016/03/14 11:33

user_detailsテーブルのchoicedはnull不可なんですね。 必要になったら入れればいいんじゃないですか?それまでは、アソシエーションで取得しても取得できませんので、無視すればいいですよね?
tacchan

2016/03/14 13:50

saveAssociatedした後にuser_detailsテーブルを確認してみると、何もsaveされていない、ということなんです。 id、user_idに数値が入っていて、choicedに入っていない、という結果になればうれしいのですが。 このようなデータを渡すにはformをどのように修正すればいいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問