ミリサイズ

頭の中をコピー・ペースト

LaravelのEloquentを使いこなせない話

Laravelのデータベース操作を学ぼうということで、Eloquent周りを色々触ってみていました。

PM17:00ごろ、「今日は時間もあるし、触り倒すぞー!」とノリノリでSublimeTextを開く私に、まさかこんな悲劇が待っていようとは、この時は思いもしないのでした……。

なお、本記事ではこんなテーブル構成を想定しています。
(実際はeventsテーブルというものもあります。カラムもだいぶ省いてます)

  • usersテーブル
カラム 詳 細
id INT 主キー。
screen_name VARCHAR Twitterで設定している名前。
screen_id VARCHAR TwitterID。
prof_image_url VARCHAR TwitterアイコンのURL。
  • sheetsテーブル
絡む 詳 細
id INT 主キー。
event_id INT 公演情報ID。外部キー。
user_id INT usersテーブルとの外部キー。
type VARCHAR 席種。

Eloquentで簡単データ取得

まずは、単純に1つのテーブルからデータを取ってくることをやってみました。

$user = User::find(1);

なんと、これだけでUserModelに紐付いたテーブル(デフォルトだとusersテーブル)から、主キーで1レコード取得できてしまいます。超簡単!

Eloquentで関連テーブルから簡単データ取得

では、usersテーブルと紐付いたsheetsテーブルからレコードをとってこようということで、やってみました。

<?php

use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;

class User extends Eloquent implements UserInterface {
    
    use UserTrait;

 // 〜中略〜

    /**
     * get the sheating information related to the user.
     *
     * @return void
     */
    public function sheets()
    {
        return $this->hasMany('Sheet');
    }

}

public function sheets()以下の定義をすると、「UserモデルはSheetモデルと一対多の関係ですよ」という意味付けになり、Userモデル経由でSheetモデルの値をとってこれるようになります。

実際に取得する部分は、こんな感じに。

$user = User::find(1)->sheets;

こうすると、Userモデルの主キー1に紐づく、Sheetモデルのレコードをとってこれます。
こんな感じでデータが扱えます。

echo $user[0]["event_id"]; // 1レコード目のevent_idの値が出力されます
echo $user[0]["user_id]; // 1レコード目のuser_idの値が出力されます
echo $user[0]["type"];  // 1レコード目の(ry

これも感動するぐらい超簡単ですね!

Eloquentで複数テーブルの結合結果を取得

ここまで順調にきてほくほく状態なわけですが、次に「あるID(users)を指定して、usersテーブルとsheetsテーブルからそのIDに該当するデータを全てとってこよう!」と思い、やってみることにしました。

書き方はこんな感じです。

$user = User::find($user_id)->with('sheets')->get();

で、sheetsテーブルの値を出力してみるぞとおもむろにキーボードに手を置く私。

「・・・どうやるんだ?」

sheetsテーブルの値って、どんな風にとれてるんでしょうか。
echo $user[0]["type];とかやったら出るのかな? よし、やってみよう。

・・・あえなくエラーで撃沈。

じゃあ、どういう風に値がとれているのか見てみよう!
ということで、中身を見てみました。

すると、こんな風にとれているようでした。 (型とか省いてて若干正確さにかけますが、こんなもんだということで)

array[0]{
 ["id"] => 123456
 ["screen_name"] => "8みり"
 ["screen_id"] => "8miri"
 ["prof_image_url"] => "http:xxx.png"
 ["sheets"] =>
   array[0]{
    ["id"] => 1
    ["event_id"] => 1
    ["user_id"] => 123456
    ["type"] => "アリーナ"
   }
 } 

なるほど…sheetsテーブルの情報は入れ子の中にくるわけだ。
ふむふむ。データ構造はわかった。

じゃあ、次はこれをTwigで出力してみよう!

{% autoescape true %}
<html>
<head>
    <meta charset="UTF-8">
    <title>TwigTest</title>
</head>
<body>
TwigTest<br>
{% for user in users %}
UserID:{{user.id}}<br>ScreenID:{{user.screen_id}}<BR>Type:{{user.sheets.type}}
{% endfor %}
</body>
</html>
{% endautoescape %}

出力結果:

UserID:1
ScreenID:8miri_dev
Type:

・・・あれ?typeが出てないな?
なんでだろう。

ここから、長い旅が始まりました。
Twigで入れ子arrayを取得できるのか調べてみたり、記法を[ ]使う方で試してみたり、色々やってみるものの一向に解決策が見つからず。

うーん困った!

結論

Eloquentの取得結果を、Twigでうまく扱えるデータ構造に入れなおしてやればいいのでしょうけど、それやるんならもうEloquent使わないほうがいいよね!!!!(泣)

ということで、明日からクエリービルダーで出直します。トホホ。

Twigでうまく扱えるよ?という情報をお持ちの方がいたら、お待ちしてます。(切実)

2015-01-31 自己解決しました!勉強不足でした!