忍者ブログ
プログラマ、ララ・ベル子さんのゆるふわ奮闘記。

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

LaravelでPHPのビルトインサーバを立ち上げてiPhoneで確認したいとき

とりあえず、題名長すぎた。

どうも、ベル子です。

-------回想シーン

3時間くらい前、午前0時すぎ。
ふと私はこんなことを思い立ってしまった。

「Laravelで今どこシートWeb版の試作を作ろうじゃないか!
 いろいろ実験的にやってみたいことがあるから、勉強も兼ねて。
 たぶんすぐ作れるし!」

説明しよう。
今どこシートとは、今だれがどこにいるのか一目で分かる機能を有し、一般的にホワイトボードなどに「NR」と書いてあって社会人になりたての時に「NR」って何ですか?と思わず聞いてしまう例のアレのことである。

いつものようにLaravelをインストールする。
migrationとかそういうのは置いておいてUIからつくることにした。
CSS3のflexboxの勉強を兼ねていろいろいじってみる。
flexboxを使うと中央揃えとか均等配置とかが超絶カンタンにできるのだが、
まだ不慣れなためいろいろやって実験してみた。
すごく面白い。

次はステータス変更の部分のUIだ。
jQueryUIのdraggableをいろいろいじってみるも、
「違う、そういうことじゃない」な出来上がりになったので
結局sortableに落ち着いた。

ここでふと思い出す。
「そういえば、jQueryUIってタッチ対応してないんだったな。
 なんかライブラリとかあるかな。
 とりあえずiPhoneで確認してみよう。」

iPhoneで確認してみようと
http://localhost:8000/
と打ってみた。

php artisan serveするとデフォルトで設定されるアドレスだ。
うっすらダメだろうなと思ってはいたが、やっぱりダメだった。

じゃあ、IPアドレスを打てばいいのかな?
よく分かんないけど、直打ちならいけるよね?そうだよね?
と女子特有の【勘でどうにかなるだろう戦法】を使ってifconfigしてみた。

AirMacを使ってるからなのか、なんかIPアドレスがちょっと複雑なことになっている。
とりあえずIPアドレスっぽいものを全部試してみる。
全部ダメだった。

やっぱりググッてみる。
私にはググるくらいの才能しかないのだとちょっと自虐的になる。
「iPhoneでMacのLocalhost見るときは{コンピュータ名}.localだぜ!」
という神々しい書き込みを見つける。

$ uname -n

すると出てくる。
今度こそ!と思って自信満々にタタンと打ってみる。

{コンピュータ名}.local:8000

でも、つながらない(´・ω・`)

いろいろ検索して、いろいろ試すもよく分からない。
さまよった挙句、

php artisan serve --host 0.0.0.0
これで立ち上げてアクセスしたまえ

という書き込みを見つける。

{コンピュータ名}.local:8000

でアクセスしてみると、わーいアクセスできたぜー!

超苦労して解決した直後に、非常に丁寧に説明してある記事を見つけた。
なんかすごく悔しかった。
だからブログを書くことにした。

超わかりやすい記事



というわけでほぼ何も出来ずに終わりました!

いい夢見れるかな。。。(´・ω・`)
オフトゥンでもふもふしよ。

拍手[1回]

PR

Eager Loadingのつづき

ちわっす。
今月のブログノルマがギリギリアウト気味のベル子です。

シルバーウィークには青森に行ってきました。
なんと東京のほうが青森より涼しいです!
寒いぞ寒いぞ詐欺ってこういうことだなって思いましたね。
東京って、やっぱ結構、寒いんですよ。

初めて青森に行ったときは、ちょっとふざけてペラペラのコンバースとか履いて行って足が凍傷になりそうになりましたけど、やや厚めのスニーカーくらいなら何とかなります。
真冬の東京の木造アパート、暖房なしのほうがよっぽど寒い自信があります。
何に対抗しているのか分かりませんがw

ということで本日もEager Loadingについてです。
先日、リレーションメソッド名にはスネークケース(something_like_this)を使わないほうがよいという話をしたと思うのですが、

> 動的プロパティでアクセスする際はスネークケースでもキャメルケースでもアクセスはできます。

とも書きました。

しかし、本日、実案件でEager Loadする際に気づいたのですが、

モデルで

public function childrenDocs()
    {
        return $this->hasMany('childrenDocs');
    }

このようなリレーションメソッドを定義してコントローラで

$some_models = SomeModel::with('parent.childrenDocs.grandChild')->get();

みたいにネストしてEager Loadして、View側で

@foreach ($some_models as $some_model)
      $some_model->parent->children_docs->grand_child->id
@endforeach

みたいに書くと、parentしかEager Loadしてくれません。

@foreach ($some_models as $some_model)
      $some_model->parent->childrenDocs->grandChild->id
@endforeach

のようにすれば、ちゃんと全てのモデルのデータをEager Loadしてくれます。

ですので、やはりリレーションメソッドは、必ず、キャメルケース(somethingLikeThis)で定義して、キャメルで呼び出すという癖をつけたほうがよさそうです。

まあ、そうだろうね。と思う話だと思うんですが、テーブル名にスネークを使っていたりすると揃えたい気持ちが湧いて、忘れてスネークで書いちゃうんですよね。視認性もいいし。

ということで、Eager Loadingをするときはキャメルケースじゃなきゃ、ダメ、絶対という話でした。


余談ですが、Eager Loadして、100以上のクエリが20とかになるとすごく気持ちがいいです。
なぜか分かりませんが、重複がなくなったぞーーーーーわーーーやったーーーーどうだーー見たかーーー!
みたいな気持ちになります。

ではでは、また近いうちにっ!

拍手[0回]

いろんなEager Loading(2)私の季節編

さて、引き続きEager Loadingについて書いていきますYO。
お気づきだと思いますが
前回、Eager Loadingについての記事なのに、Eager Loadingについて何の説明もせずに終わらせたベル子です。てへぺろ

突然ですが、私の一番好きな季節は秋です。
ご飯も美味しいし、紅葉も綺麗だし、気候もちょうどいい。
日本の一番に気に入ってるところは、秋があるというところと言っても過言ではありません。

落ち葉が舞う上野公園を少し散歩してから、国立西洋美術館で絵画を眺める。
少し肌寒いなあと思いながら、チャイを片手にベンチでミステリー小説を読む。
青梅街道のイチョウ並木沿いを自転車を走らせ、新宿に映画を観にいく。

孤独で気ままな生活が懐かしいです。
1日でいいから、そんなことをして過ごしたいなぁと切望する毎日です。
I'm eager to spend time doing things like that.

Eagerの英語での使い方を紹介してみました。

さて、おさらいです。
記事の一覧を表示し、記事に紐づくユーザー名を表示する場合で考えてみます。
↓のようにControllerに書いて、view側にarticlesのオブジェクトを渡すとします。

$articles = Article::all();

return View::make('articles')->with('articles', $articles);

そしてview側でこのように書くと、usersテーブルのrowを取得するクエリがN+1回走ってしまいます。

@foreach ($articles as $article)
     <h2>{{{$article->title}}}</h2>
     <p>posted by {{{$article->user->name}}}</p>
@endforeach

このような場合に、先行して1回のクエリで、関連したusersのデータを全て取ってきてくれるのがEager Loadingというしくみです。

では実際の書き方の紹介をします。

$articles = Article::with('user')->get();

簡単ですね。
先行して欲しいデータのリレーションメソッド名をwithメソッドの引数に入れるだけです。

このようにシンプルな関係を表現したいだけなら、とても簡単なのですが、実際のシステムを作る場合には、こんなにシンプルにはいきません。
テーブルはもっと複雑に絡み合っていて、表示させなければならないデータもたくさんあります。

たとえば、記事には筆者と編集者と提供した会社が紐付いているとしたらどうでしょうか。
まずはモデルでリレーションを定義します。

class Article extends Eloquent {

    public function writer()
    {
        return $this->belongsTo('Writer');
    }

    public function editor()
    {
        return $this->belongsTo('Editor');
    }
    public function company()
    {
        return $this->belongsTo('Company');
    }

}

@foreach ($articles as $article)
     <h2>{{{$article->title}}}</h2>
     <p>筆者: {{{$article->writer->name}}}</p>
     <p>編集者: {{{$article->editor->name}}}</p>
     <p>提供社: {{{$article->company->name}}}</p>
@endforeach

上記の場合、記事が10本あると、なんと31回もクエリが走ってしまいます。
(やってみてないけど多分そうです。)

ここでようやく本当の本題であるEager Loadingのいろいろな書き方の紹介をしたいと思います!


★1、複数のリレーションデータをいっぺんに取得したい。

上記のようなパターンで、すべてのリレーションテーブルのデータをEager Loadingするには下記のように書きます。


$articles = Article::with('writer', 'editor', 'company')->get();

このように書くことで今まで31回クエリが走っていたところ、4回のクエリで済むのです!
(やってないから、やってみて確かめてみてください。)


★2、さらに先のリレーションデータまでいっぺんに取得したい。

例えば、編集者は提供社に所属しているので、編集者のクラスに提供社とのリレーションが定義されているようなネスト構造になっているデータを取得したい場合です。

@foreach ($articles as $article)
     <h2>{{{$article->title}}}</h2>
     <p>編集者: {{{$article->editor->name}}}</p>
     <p>提供社: {{{$article->editor->company->name}}}</p>
@endforeach

このように取得しようとすると、10本記事があると21回のクエリが走ってしまいます。
しかし、ネストしているリレーションも、↓このように取得することができるんです!
すごいですね、Laravel。

$articles = Article::with('editor.company')->get();

このように書いておくと、21回走っていたクエリが3回で済むようになります。
(何度も言いますが、やってみてないです。)

★3、リレーションテーブルのデータ取得に条件を足したい。

例えば、編集者が退職していた場合、記事一覧には編集者名を表示したくないのでdeleted=1のものは表示したくない、のような場合です。

リレーションメソッド内に条件をチェーンでつなげることはもちろんできるのですが、リレーションメソッドはいろんな場所から参照していることが多いと思うので、イレギュラーな表示パターンが出てきてしまった際に、『今回だけ条件を足したい』のようなことがあります。

そんなときは以下のように、withメソッドの引数を配列にしてクロージャーを渡してやることで、リレーションテーブルの取得に、新たなクエリを追加することができます。

$articles = Article::with(['editor' => function ($query) {
    $query->where('deleted', 0);
}])->get();


★4、何かの条件のときだけ、Eager Loadingしたい。

例えば、ログインユーザーが筆者の時だけ編集者と提供社を一覧に表示するので、そのときだけEager Loadingしたい、のような場合です。

$articles = Article::all();

if ($user->role == 'writer') {
    $articles->load('editor', 'company');
}

このことを、Laravelサイトでは、"Lazy Eager Loading"と表現しています。

おいおいLazyなのかEagerなのか訳わからんじゃないか。
ネーミングセンスw
先にモデルを取得しちゃったけど、あとから追加でEager Loadしたくなったときに使ってね!ってことですかね。

このようにEager Loadingの仕方にもいろいろあるんですね。
非常に便利です!
こんなふうに書かなくても全部モデル内で別メソッドにしてやるぜ!という声が聞こえてきそうですが、いろんな書き方があるということを知ってると、あとで何か困ったことがあったときに使えるかもしれないです。

あと、不確かなのですが、Eager Loadしたデータにクエリを加えて再度get()だのfirst()だのしてしまうと、Eager Loadingしてくれなくなるような気がしています。
どうしてもEagerできなかったら、諦めるほかないということでしょうね。

まだまだピヨピヨなので、分からないことだらけなのですが、Eager LoadingやORMと上手に付き合って、スッキリきれいで読みやすいコードが書けるように精進していきたいです!!

ホントはコードを書いて確認してからアップしようと思ってたのですが、最近、デスノートをhuluで見始めたら面白くて止まらなくて(*´ω`*)

そのうち実際にコード書いて確かめてみますー。

拍手[2回]

いろんなEager Loading(1)ひみつ道具編

こんばんは。ベル子です。
今は、夜中の2時です。眠いです。

1時くらいから書き始めたのですが、本当に無関係なことを書き出したら、話の収集がつかなくなったので、もう一度はじめから出直すことにしました。
人生と違ってブログはいつでも出直せるからいいですね。

さて、関係ない話で始まりましたが今日はEager Loadingのお話です。

突然ですが皆さんは以下のどれ派ですか?

1. Eager Loading
2. Eagerローディング
3. イーガーローディング
4. 事前に一括で関連データをロードしてくれるやつ
5. Eagerとか言わずに、要するに『先行ローディング』でよくないですか
6. Eager Loading??何それこわい。でも美味しいんですよね!知ってます。

私はですね、断然6番派だったんですよ。
Eager Loadingとか難しい名前がついていますが、分かってしまえば簡単です。
全国中学校放送コンテスト東京地区大会アナウンス部門第3位にして、N◯K評価が出場者の中で最も高かったという武勇伝を持つ放送部部長、兼、演劇部副部長の私ですからね。
小難しい名前の得たいの知れない機構すらも、ほんの4ヶ月くらいで理解できます。

私のように、内気だけど好奇心旺盛な初心者のために、分かりやすく説明したいと思います。
LaravelのORM(オブジェクト関係マッパー)であるEloquantを使うとデータベースtable同士の関係を定義することができます。


class User extends Eloquent {

    public function articles()
    {
        return $this->hasMany('Article');
    }

}

ユーザーがログインして記事を書くようなアプリの場合、ユーザーにはたくさんの記事が紐づきます。articlesというテーブルの行には同じuser_idが何回も出てくるような関係です。

このように関係を定義すると

$articles = User::find(1)->articles;

こんなふうに、usersテーブルのid=1の人が書いたarticlesテーブルのデータ全件が取得できます。

ここで私のようにphpもオブジェクト指向もフレームワークも人としての成熟度も初級でピヨピヨの人は、こんな疑問が湧くことでしょう。
メソッドで定義したのに、なぜプロパティでアクセスできるの?

そこのピヨ子さん、いい質問ですね!!
これは『動的プロパティ』といって、↓のように書くべきところを、上記のように書けばデータを取ってきてくれるというものです。

$articles = User::find(1)->articles()->get();

ピヨ子「省略してるだけじゃん、どこが動的なの?」

動的プロパティが賢いのは、関係してるデータが複数のデータなのか1つのデータなのかを判断して自動的にget()かfirst()でデータを取ってきてくれるんです。
分かったか、ピヨ子よ。

例えば、ユーザーの住所を別テーブルで管理したいような場合、
ユーザーアカウントのテーブルとユーザーの住所を保管するテーブルとの関係は1対1です。
その場合は、hasOneというメソッドで関係を定義できます。

    public function address()
    {
        return $this->hasOne('Address');
    }

そして以下のように書くと

$address = User::find(1)->address;

以下のようなデータを取ってきてくれます。

$address = User::find(1)->address()->first();

動的プロパティのさらに便利なところは、こんなふうにテーブルのカラムデータを取ってこれるところです。

$zip_code = User::find(1)->address->zip_code;

以下のように書くのと同義です。ずいぶん見やすいですよね。

$zip_code = User::find(1)->address()->first()->zip_code;

しかし、便利だけど混乱しやすいのが、この動的プロパティで

User::find(1)->articles->title;

としても記事のタイトルは取れません。

なぜかというと、記事は複数あるので、動的プロパティでデータを取得すると、get()したときと同じようにCollectionという配列をラップしたあの例のやつが返ってくるからです。
例のやつが返ってくるということは、以下のようにすれば、ちゃんとカラムのデータを取ってこれます。

$user = User::find(1);

foreach($user->articles as $article) {

    $title =  $article->title;

}

簡単ですね!
ちなみにメソッドで終わらせるとクエリが返ってくるようなので、気をつけてください。

$user = User::find(1)->address();
↑こういう終わり方をするとデータではなくクエリが返ってきます。

あと、このリレーションメソッドのメソッド名には(_)アンスコを含まないほうがいいです。
メソッド名にアンスコを含めると動的プロパティでのアクセスができなくなります。
メソッド名でクエリをつなげる場合はアンスコを含んでいても大丈夫ですが、リレーションメソッドとしての使い勝手が悪いので、リレーションメソッドにはアンスコは使えないと覚えたほうがいいでしょう。
メソッド名をキャメルケースで定義した場合、動的プロパティでアクセスする際はスネークケースでもキャメルケースでもアクセスはできます。

some_documents() ←これだとダメ
someDocuments() ←これだとOK
User::find(1)->some_documents ←これでもアクセスできる!
User::find(1)->someDocuments ←これは、もちろんOK 


さて、前置きが長くなりましたが、ここからが本題です!

hasManyの関係のときに下記のようなコードを書いた場合、
11本の記事があったとすると12回のクエリが走ってしまいます。
1回目はユーザーに紐づく記事を取得するクエリで
それ以外の11回は、それぞれの記事に紐づくタイトルを取得するクエリです。

foreach($user->articles as $article) {

    $title =  $article->title;

}


これがいわゆるN+1問題とかいうやつです。
初めて読んだときは全く意味が分からなかったのですが、コードを書いてデバッガーでクエリを見てみるとよく分かります。
viewに何か大量なデータを渡して、viewの中でforeachを回してリレーションしているデータを取得してみてください。

ごらん、同じクエリが何回も登場しているよ。
1000件のデータがあったら1000件分、同じクエリが登場しているよ。

そしてあなたは思うはずだ。
同じこと何回もするのは、やっぱり効率が悪いんじゃなかろうか。
どうにかならんの?これ。
ドーラーえーもーーーん。

ええ、そういうときに使うのが、Eager Loadingです!!テッテレッテテテーテッテー!

いや〜ちょっと長くなってしまいました。
本題に辿りつけませんでしたが、さすがに眠くてたまらないので、続きは次回にしましょう!
次回は、Eager Loadingのあんなパターンやこんなパターン、さらにムフフなパターンまでご紹介します。

お楽しみにね♥

拍手[1回]

MacにMySQLをインストールして3コマンドでLaravelをどーんの巻

どうも!
久しぶりですね。みなさん元気にしてましたか。
「内容はともかくとして、息抜きにいいよね」とブログをボスに褒められたベル子です。

内容で勝負してるつもりだったのに!

いえ、でも褒めてくれる人がいるのは嬉しいことです。

先日、このブログを全く読んでいないことを確信しているので登場させたい放題に登場させている、師匠ことO様にも遠回しに通訳つきで褒めていただきました。
おそらく、「頑張ってるよね!」と褒めてくれたんだと思うのですが、分かりづらすぎて自信ないです(爆)
通訳してくれたM先輩、ありがとうございました。
お二人とも、とても大好きな先輩です。

雑談はこのくらいにして、本題に入ります。
自宅でLaravelの勉強をするときに、簡単なテストコードを書くために、いちいちVM(ヴァーチャルマシン)を立ち上げるのが面倒になってきたので、MacにMySQL入れちゃえば、Mac上でLaravel動かせるんじゃないの?そうだよね?ということに、ようやく気付きました。

なぜもっと早く気づかなかったのか。
激しく後悔、ハゲ校するほど便利です。

ということで、手順を早速まとめたいと思いまぁーす♪
XcodeとかHomebrewとかComposerとかPHPとか、そんなのはとっくにインストールしてあるよって人はその部分のステップを飛ばしてください。

★Step.1
Xcodeをインストール
App Storeで検索してインストール

★Step.2
Homebrewをインストール
公式サイトにあるコマンドをコピってターミナルに貼り付けてインストール
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

★Step.3
PHPを5.6にする
↓このサイトの通り、Macに入っているPHPを5.6にする
macにhomebrewでPHP5.6環境をインストールしてみる

★Step.4
MySQLをインストール
↓このサイトを参考にHomebrewでMySQLをインストール
Mac へ MySQL を Homebrew でインストールする手順

とは言え、以下の2行をコマンドーんするだけ。
$ brew update
$ brew install mysql

★Step.5
MySQLを立ち上げる
$ mysql.server start

★Step.6
ComposerをMacにインストール
$ brew install composer

★Step.7
Laravelをインストール
Mac上のお好きな場所にLaravelをインストール(無邪気にデスクトップなんかでもおk)
{directory}の部分は任意のディレクトリ名

Laravel 5.1
$ composer create-project laravel/laravel {directory} --prefer-dist

Laravel 5.0
$ composer create-project laravel/laravel {directory} "~5.0.0" --prefer-dist

Laravel 4.2
$ composer create-project laravel/laravel {directory} 4.2 --prefer-dist

★Step.7
データベースを作る
{db_name}の部分は任意のデータベース名
$ mysql -uroot
$ CREATE DATABASE {db_name};

★Step.8
プロジェクトディレクトリ直下にある.envファイルを開いて、データベースの設定をする(Laravel 5~)
※以下はlaravelというデータベースを作成した場合


★Step.9
プロジェクトディレクトリに移動しビルトインサーバを起動する
$ php artisan serve

★Step.10
ブラウザでhttp://localhost:8000/にアクセス!
止めるときは Ctrl+C だよ。

あとはMigrationでテーブル作ったりなんなり好き放題やってください。

MySQLを止めるときは以下のコマンドです。
$ mysql.server stop


Sequel Proを使ってる方は以下の設定でDBに接続できます。


ちょっとした勉強で少しいじりたいというときに、3コマンドくらいで立ち上げてテストできます。恐ろしく便利んぐです。

あーもっと早く気づいてたら、よかったのに!と思いましたが、いろいろVMの設定やらで困ったおかげで知識は増えたと思うので、四苦八苦してハマったり絶望したり発見したりすることって大事だなって思います。悩んで解決したことって本でつらつらと読むよりも、よく覚えられます。


↓ここからは完全に話が脱線するので、暇で暇でしょうがない人か息抜きしたくてたまらない人用です。
以前、エンジニアをやりながら字幕翻訳の仕事もやっていたのですが、「どこで翻訳の勉強をしたのか」「どうしたら翻訳者になれるのか」という質問をよくされるんですよね。「私もやってみたいなー。自宅で仕事できて、経費もかからないし、子育てとの両立もできるしいいよねー」とか言われるんです。
もう慣れたので「うん。まあ確かにね」くらいの感じで適当に返事をするようにしてるのですが、
たぶん世間の人の翻訳者に対するイメージって「語学力があるだけで、文字を書いて生活できるなんて、楽そう!」なんですよね。

翻訳はある意味、自分との戦いです。見えない正解がどこかに一つだけあって、それを砂の中から必死に探すような感覚です。そして、自分が3日間ほとんど寝ないで考えたセリフについて、他人から批判されるということを受け入れなければいけません。
チェッカーに監修、納品先のディレクターそして最後は視聴者です。

それから、納期を落とすと放送事故になってしまうというプレッシャーとの戦いでもあります。
だから3ヶ月持てばいいほうで、ほとんどの人がすぐに辞めてしまいます。
必死に書いた翻訳も新人の場合は、半分以上、手直しされます。
痛烈なダメ出しつきで、ギャラもほとんどタダみたいな値段です。

それに翻訳者は翻訳だけしてるわけではなく、ハコ書きというセリフを何フレーム数出すかという作業もしていますし、聞き取りもしています(スクリプトがある場合もあります)。
すべて翻訳されているように見えて、ここは要らないというように字幕が出ていないものなどもあります。そういうのを2割り程度の手直しに収まるくらいのクオリティーで一人で仕上げて、ようやく一人前のギャラがもらえます。

あと、「なんか翻訳がダサい。日本語のボキャブラリーが少ない。」のような印象を持たれると仕事をもらえなくなります。
文章翻訳はハコ書きはありませんが、大量にものすごい短期で翻訳していくことが多くて専門用語も多かったりして、調べ物が多くて大変です。

その点、プログラミングの場合は、同じように大変でも、周りから「大変そうだね。すごく勉強しないといけないでしょ?夜、寝れてる?」と心配してもらえるので、このイメージの違いは何なんだろう?とか思っちゃいます。

プログラマが楽だとは言わないですが、夜はちゃんと寝れてますし、ボスや先輩たちも愉快な仲間たちばかりです。

どちらも大変だけど、仕事としてのやりがいはすごくあります。

最後はいったい何のまとめだか分かりませんが、翻訳はそんなに甘くないぞってこととLaravelはいつでも3コマンドでどーんできるぞってことですね、はい。

では、また会える日まで。
I'll get back to ya soon!!

拍手[0回]