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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

FuelPHP

FuelPHPは、軽量高速で開発が可能なPHPのWebアプリケーションフレームワークです。

Q&A

解決済

2回答

695閲覧

FuelPHPでhas_one関係である2つのテーブルに同時にInsertしたい

PenelopeG

総合スコア31

MySQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

FuelPHP

FuelPHPは、軽量高速で開発が可能なPHPのWebアプリケーションフレームワークです。

0グッド

0クリップ

投稿2017/08/29 12:49

###実現したいこと
FuelPHPで管理者が新規会員を登録する機能を作っています。
has_one関係にあるusersテーブルとprofileテーブルに同時にInsertしたい。

FuelPHP1.8
データベースにはMySQLを使用しています。

###テーブル
usersテーブル

sql

1CREATE TABLE IF NOT EXISTS `users` ( 2 `id` int(11) unsigned NOT NULL PRIMARY KEY, 3 `username` varchar(30) NOT NULL, 4 `password` varchar(255), 5 `email` varchar(255) NOT NULL, 6 `created_at` int(11) NOT NULL, 7 `updated_at` int(11) NOT NULL DEFAULT 0 8) ENGINE=InnoDB DEFAULT CHARSET=utf8;

profileテーブル

sql

1CREATE TABLE IF NOT EXISTS `profile` ( 2 `profile_users_id` int(11) unsigned NOT NULL PRIMARY KEY, 3 `profile_name` varchar(20) NOT NULL, 4 `profile_address` varchar(100), 5 `profile_created_at` int(11) NOT NULL, 6 `profile_updated_at` int(11) NOT NULL DEFAULT 0 7) ENGINE=InnoDB DEFAULT CHARSET=utf8;

###モデル
APPPATH/classes/model/user.php

php

1class Model_User extends \Orm\Model 2{ 3 protected static $_table_name = 'users'; 4 5 protected static $_primary_key = array('id'); 6 7 protected static $_properties = array( 8 'id', 9 'username', 10 'password', 11 'email', 12 'created_at', 13 'updated_at', 14 ); 15 16 protected static $_observers = array( 17 'Orm\Observer_CreatedAt' => array( 18 'events' => array('before_insert'), 19 'mysql_timestamp' => false, 20 ), 21 'Orm\Observer_UpdatedAt' => array( 22 'events' => array('before_update'), 23 'mysql_timestamp' => false, 24 ), 25 ); 26 27 protected static $_has_one = array( 28 'profile' => array( 29 'key_from' => 'id', 30 'model_to' => 'Model_Profile', 31 'key_to' => 'profile_users_id', 32 'cascade_save' => true, 33 'cascade_delete' => false, 34 ) 35 ); 36}

APPPATH/classes/model/profile.php

php

1class Model_Profile extends \Orm\Model 2{ 3 protected static $_table_name = 'profile'; 4 5 protected static $_primary_key = array('profile_users_id'); 6 7 protected static $_properties = array( 8 'profile_users_id', 9 'profile_name', 10 'profile_address', 11 'profile_created_at', 12 'profile_updated_at', 13 ); 14 15 protected static $_observers = array( 16 'Orm\Observer_CreatedAt' => array( 17 'events' => array('before_insert'), 18 'mysql_timestamp' => false, 19 'property' => 'profile_created_at', 20 'overwrite' => true, 21 ), 22 'Orm\Observer_UpdatedAt' => array( 23 'events' => array('before_update'), 24 'mysql_timestamp' => false, 25 'property' => 'profile_updated_at', 26 ), 27 ); 28 29 protected static $_belong_to = array( 30 'users' => array( 31 'key_from' => 'profile_users_id', 32 'model_to' => 'Model_User', 33 'key_to' => 'id', 34 'cascade_save' => false, 35 'cascade_delete' => false, 36 ) 37 ); 38}

###コントローラのアクション

php

1public function action_create() 2{ 3 if (Input::method() == 'POST') 4 { 5 $user = Model_User::forge(array( 6 'username' => Input::post('username'), 7 'password' => base64_encode(hash_pbkdf2( 8 'sha256', 9 Input::post('password'), 10 \Config::get('auth.salt'), 11 \Config::get('auth.iterations', 10000), 12 32, 13 true 14 )), 15 'email' => Input::post('email'), 16 'created_at' => \Date::forge()->get_timestamp(), 17 'updated_at' => 0, 18 )); 19 20 $user->profile = Model_Profile::forge(array( 21 'profile_name' => Input::post('profile_name'), 22 'profile_address' => Input::post('profile_address'), 23 'profile_updated_at' => 0, 24 )); 25 26 if ($user and $user->save()) 27 { 28 // 登録成功 29 Session::set_flash('success', '新しい会員『'. $user->profile->profile_name .'』を追加しました。'); 30 Response::redirect('admin/member/index'); 31 } 32 } 33 34 $this->template->title = "新規会員登録"; 35 $this->template->content = View::forge('admin/member/create'); 36} 37

※バリデーションに関する記述は省略しています。

###困っていること
これで、usersテーブルとprofileテーブルのそれぞれにInsert文が実行されると思ったのですが、
usersテーブルにしかInsertされませんでした。

ここまでは以下のドキュメントを参考にしました。

FuelPHP日本語ドキュメント > ORM > リレーション:Has One
http://fuelphp.jp/docs/1.8/packages/orm/relations/has_one.html

試しに、コントローラの以下部分、

php

1if ($user and $user->save())

ここを次のようにしてみたら、profileテーブルにもInsertできましたが、
profile_users_idが正しく(意図した通りに)セットされませんでした。

php

1if ($user and $user->save() and $user->profile->save())

2つのテーブルにInsertする方法をご教授いただけますと幸いです。

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

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

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

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

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

guest

回答2

0

Tomakさんに教えていただいた内容を元にたどりついた結果です。
$user->save()だけで意図したとおり、2つのデーブルにInsertすることができました。

php

1public function action_create() 2{ 3 if (Input::method() == 'POST') 4 { 5 try 6 { 7 // トランザクションスタート 8 \DB::start_transaction(); 9 10 $user = Model_User::forge(array( 11 'username' => (string) Input::post('username'), 12 'password' => base64_encode(hash_pbkdf2( 13 'sha256', 14 (string) Input::post('password'), 15 \Config::get('auth.salt'), 16 \Config::get('auth.iterations', 10000), 17 32, 18 true 19 )), 20 'email' => Input::post('email'), 21 'created_at' => \Date::forge()->get_timestamp(), 22 'updated_at' => 0, 23 )); 24 25 $user->profile = new Model_Profile(); 26 $user->profile->profile_name = Input::post('profile_name'); 27 $user->profile->profile_address = Input::post('profile_address'); 28 $user->profile->profile_updated_at = 0; 29 30 // DB保存 31 if ($user->save()) 32 { 33 // コミット 34 \DB::commit_transaction(); 35 36 // 登録成功 37 Session::set_flash('success', '新規会員『'. $user->profile->profile_name. '』を追加しました。'); 38 Response::redirect('admin/member/index'); 39 } 40 41 // ロールバック 42 \DB::rollback_transaction(); 43 } 44 catch (\Exception $e) 45 { 46 // ロールバック 47 \DB::rollback_transaction(); 48 49 Session::set_flash('error', '登録できませんでした。'); 50 } 51 } 52 53 $this->template->title = '新規会員登録'; 54 $this->template->content = View::forge('admin/member/create'); 55}

投稿2017/08/30 11:17

PenelopeG

総合スコア31

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

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

0

ベストアンサー

ダンプするとわかるかと思いますが、$user->profile\Model_Profileオブジェクトが既に生成されているはずです。ですので、$user->profile->カラム名としてそのまま続けることができます。

あとは、$user->save()をすると、勝手に$user->idauto_incrementされたIDが入っています。
トランザクションと、try~catchを入れるとこんな感じだと思います。

FuelPHPで新規登録などを実装するならSimpleAuthを使用すると便利だと思います。拡張も簡単にできます。

php

1public function action_create() 2{ 3 if (Input::method() == 'POST') 4 { 5 try { 6 // トランザクションスタート 7 \DB::start_transaction(); 8 9 $user = Model_User::forge(array( 10 'username' => Input::post('username'), 11 'password' => base64_encode(hash_pbkdf2( 12 'sha256', 13 Input::post('password'), 14 \Config::get('auth.salt'), 15 \Config::get('auth.iterations', 10000), 16 32, 17 true 18 )), 19 'email' => Input::post('email'), 20 'created_at' => \Date::forge()->get_timestamp(), 21 'updated_at' => 0, 22 )); 23 24 $user->save(); 25 26 if (!empty($user->id)) 27 { 28 $user->profile->profile_users_id = $user->id; 29 $user->profile->profile_name = Input::post('profile_name'); 30 $user->profile->profile_address = Input::post('profile_address'); 31 $user->profile->profile_updated_at = 0; 32 33 $user->profile->save(); 34 35 // コミット 36 \DB::commit_transaction(); 37 38 // 登録成功 39 Session::set_flash('success', '新しい会員『'. $user->profile->profile_name .'』を追加しました。'); 40 Response::redirect('admin/member/index'); 41 } 42 43 // ロールバック 44 \DB::rollback_transaction(); 45 } 46 catch (\Exception $e) { 47 // エラー処理 48 // ロールバック 49 \DB::rollback_transaction(); 50 } 51 } 52 53 $this->template->title = "新規会員登録"; 54 $this->template->content = View::forge('admin/member/create'); 55}

投稿2017/08/30 05:05

Tomak

総合スコア1652

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

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

PenelopeG

2017/08/30 11:15

さっそく試してみました。 私の理解不足もあり、途中エラーが出たりしましたが、いただいた以下をヒントを元に乗り切ることができました。 ありがとうございました!!! ・$user->profileに\Model_Profileオブジェクトが既に生成されているはず ・$user->profile->カラム名としてそのまま続けることができる ・$user->save()をすると、勝手に$user->idにauto_incrementされたIDが入っています あとは、おっしゃるとおりSimpleAuthを使用したいので、 AuthインスタンスとModel_Userインスタンスと、いまいち理解できていないところがありますが、 試行錯誤してみようと思います。
Tomak

2017/08/30 11:53

あ、すみません。確かにトランザクション使ってるので、私のコードだとエラーになってしまいますね。
PenelopeG

2017/08/30 14:04

いえ!とんでもないです!回答いただいたからこそ上手くいきました。 トランザクション、try〜catchなど、まだまだ理解不足が多く、とても勉強になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問