2019年抱負

今年の年末にちゃんと答え合わせできるよう、簡単にだけど今年の目標を書いた。この一年は、もっとWebのスキルをつける年にしたい。2800hぐらい時間積みたいと思ってる。

  • 1700時間ぐらいは、お仕事の時間でいろいろ学べるように頑張る
  • 1100時間は、足りないスキル、気になるスキルキャッチアップする時間にする

今年1年でWebアプリケーションエンジニアとちゃんと名乗れるようになるのが目標

  • まだまだ初心者感が抜けてないと思ってるので、今年1年で脱初心者、中級者になれるようにする
  • rails,laravelのフレームワークをちゃんと使いこなせるようになりたい
  • ちゃんとっていうとあれだけど、アプリケーションを作る際に考慮すべきことを知っていて、それについて議論できて、決まったことをコードで表現できるようになる
  • そのための具体的なTODOは、都度考えながら、仕事で学んだり、本読んで学んだり、軌道修正しながら進めて行きたい

とりあえず今年インプットしておきたいと思ってるリスト

基礎力足りないと思ってて、ちゃんと読み切りたいと思ってる本のインプットと、手を動かして作りたいと思ってることリスト。仕事で使うスキルを中心にいい感じでキャッチアップできたらいいなあと思ってる。本読む、手を動かす、その結果をブログに書く、みたいなサイクルをたくさんしたいと思う。時間割は適当(本については1章3hとかの計算)

  • rubyオブジェクト指向本(30h)
  • laravel本(50h)
  • laravelオープンソースプロジェクトを読む(40h)
  • laravelで自作アプリ(50h)
  • 現場ruby本(30h)
  • javascript本格入門本(50h)
  • churakariリリースする(150h)
  • isucon周りの勉強(200h)
  • 実践コンテナ本読む(30h)
  • hello,world gem

資格

体系的に理解していけるように資格も取れたらいいなあと思ってる

kakakakakku.hatenablog.com

kiryuanzu.hatenablog.com

アウトプット

  • ブログ

    • とりあえず、クオリティ低くても、たくさん書くことと、誰かが読んでることを意識して丁寧に書くようにする(脱メモ)
  • LT

    • チャンスを見つけて挑戦したい(人前で話すの苦手なので、頑張っていきたい)

まとめ

今年も頑張っていきたい。よろしくお願いします!

2018年振り返り

今年の振り返りを簡単に書いた

今年やったこと

  • 時系列に並べてみた
    • 1月 プログラミングスクール
      • html css js php web基礎全般(100h)
    • 2月プログラミングスクール
      • html css js php web基礎全般(100h)
    • 3月 ruby/rails(100h)
      • progate ruby
      • ドットインストール(sinatra,active record)
    • 4月 ruby/rails(100h)
    • 5月 ruby/rails(100h)
      • rails tutorial 1周目
    • 6月 ruby/rails(100h)
      • rails tutorial 2周目
    • 7月 ruby/rails
      • churacari
        • さぼさん、仲嶺さんと一緒にやり始めた趣味プロジェクト
        • 来年はchurakariリリースしたい
    • 8月 ruby/rails
      • churacari
    • 9月 laravel 実務経験
    • 10月 laravel
      • laravelお勉強で個人アプリ作る
    • 11月 laravel 実務経験
    • 12月 laravel 実務経験

今年振り返り

  • railsチュートリアル2週目終わったぐらいから時間計測しなくなったけど多分1000hは学習時間積めた
  • railsチュートリアルと実践的な開発の間にはかなり高い壁があると感じた
  • 今年やったことを時系列並べてみると、頑張ったなあという気持ちと、もっとできたんじゃないかなあという気持ちがあって、もっとできてんじゃないかと思うところとしては、あまりアウトプットできてないところ

    • もっとアウトプットする
      • アウトプットがあるほどインプットできる
      • 一応ブログ書いてるけど、メモ感が強いので、もう少し丁寧に、誰かの参考になるように書く
      • LTとかもっとできるようにする
      • 作ってみた、やってみたの量をもっと増やす
      • コード書いてる時間が単純に少ない問題もある
  • 10月以降はプロジェクトに参加させてもらってめちゃめちゃ勉強になった

    • レビューしてもらえること
      • 個人で学習してるだけだと、それが正しいか判断できないからレビューしてもらえるってことは一番勉強なる
    • チームメンバー間のやりとりをみれる
      • コミュニケーションから学ぶこと多くて、いろいろ教えていただいたり、チームメンバー間のやりとりの内容の意味わからない場合、それが自分に足りてないことで、自分がわかってないことが浮き彫りになるので、良い
    • 実際に動いてるコードを読める
      • 個人学習とか趣味レベルだと仕事で使われてるアプリがどんな感じなのかあまりイメージできなかったけど、実際のコードを見れるってのは勉強になった。最初見たとき、めちゃめちゃクラスがあって、これが実務経験か!!!って気持ちになった
    • 初歩的なところでこけてる
      • めちゃめちゃ初歩的なところでこけるとか度々あって、実務経験積みつつも、基礎力を並行して向上させて行かなきゃいけんなあと感じた
    • 設計むずい
      • コード書き始める前に、まずどういうものを作るのかっていうissueを作ったりするのが、難しいと感じた。どういうポイントを考慮しないといけないのかみたいなところがまだつかめていないと思う
  • もっと言語化
    • ここまで振り返っていて、勉強になったとか、うまくできてない、とかの振り返りがあるけど、それをもう少しちゃんと言語化して、振り返れるようになった方がいいと思ったので、曖昧な言葉で流されないように気をつける
      • 何が勉強になったのか
      • 何ができていないのか
      • そのために何をするのか

まとめ

  • 今年は、アプリケーションを書けるエンジニアになるべくスタートラインに立てるよう、頑張った一年だった。ただ、まだまだ力不足なので来年は今年の三倍頑張りたいと思う。もっとコード書く。
  • あと、プログラミングの勉強を本格的に初めて、同じような目標に向かって頑張ってる仲間もたくさんできたのがよかった。切磋琢磨していけるよう頑張る

条件式を書くときは、明示的にわかりやすくするよう心がける。()をつける

条件式を書くときに、条件が長くなっちゃうと、それがぱっと見どういう条件なのかわからなくなるので、カッコとかつけて、読みやすくするのを心がける。

() を付ける

以下、内容は適当だけど、()で囲んだほうが見やすい。

$user->post_id == $post->id && $user->isPost() || $user->isTask();
($user->post_id == $post->id && $user->isPost()) || $user->isTask();

初歩的過ぎるとこだけど、コードレビューしてもらって、気づけたことで今後気をつける。明示的にわかりやすいを意識して書けるようにしていきたい。() 付けるのは初歩的すぎなので他にも意識する(いろんな人のコード読みつつ、実務経験を積みつつ勉強する!)

演算子の優先度

あと、演算子の使い方で、優先順位があるのちゃんと把握してなかったので気をつける。(or より andのほうが優先度高い!)

演算子の優先順位

http://php.net/manual/ja/language.operators.precedence.php

Laravelの認可処理

最近、Laravelの認可処理を実装する際に学んだことを書きます。

やりたいこと

  • ユーザーの役割に応じて、アクセス制御できるようにしたい。例えば、Adminユーザーだったら編集/削除/登録の操作できるけど、それ以外のユーザーの場合は、参照する権限しかない、みたいなことをできるようにしたい。

  • 認可処理で設けた利用制限について、どの処理に対して、どういう認可の処理が適用されてるかを php artisan route:list の実行結果で、すぐわかるようにしたい(なのでミドルウェアによる認可が必要。コントローラーの各アクションに定義すると、どの処理にどの認可処理が適用されてるか、route:list とかでぱっと見わからない)

  • ただ、Laravel 5.1を使っていて、ミドルウェアで認可できるようにしたいんだけ、5.1では対応してないようだったので、can ミドルウェアを laravel 5.1で使えるようにしたい

やったこと

  • Laravelで用意されてる認可処理、ポリシーを使った
  • Laravel 5.1でcanミドルウェアを使えるようする。Laravel 5.3以降で、Laravelが標準で用意しているcanミドルウェアのファイル(Illuminate/Auth/Middleware/Authorize.php)を5.1環境に配置して使えるようにする
  • ルートパラメーターからミドルウェアインスタンスを渡せるようにした(モデル結合ルート)。それを元にポリシーの認可の条件を書けるようにした

Laravelで用意されてる認可処理、ポリシーを使った

Laravelでは、認可処理が2種類用意されてて、詳細はドキュメント。 https://readouble.com/laravel/5.7/ja/authorization.html

  • 1つの認可処理に名前をつけて利用の可否を決定づけるゲート(Gate)

  • 複数の認可処理を記述できるポリシー(Policy)

これ、どういう状況でゲート使って、どういう状況でポリシー使った方が良いか、ちょっとよくわからなかったんだけど、使い分けとして、特定のリソースの操作に対して、認可する場合はポリシーを使って、グローバルで認可の制限をつけたい場合は、ゲートを使うのが良さそう。今回の場合でいうと、特定のリソースに対しての編集/削除/登録の認可になるので、ポリシーを使って書いた。Gateを使って良くなそうな例として、Gateで認可の条件を書いていくとすると、AuthServiceProviderのbootメソッドに、大量に処理を書いていく可能性があり、パッとみて、どういう制御がかかっているかわかりずらくないっていく懸念がありそう。特定のリソースに対する制御の場合は、ポリシーを使って書いていった方がわかりやすくて良さそう。以下、ポリシーを使う場合のざっくりした流れ。詳しいところはドキュメントに載ってる。

(1) xxxリソースに対応したポリシーを作成する

$ php artisan make:policy xxxxPolicy

(2) ポリシーを登録する。AuthServiceProvider の$policies に作成したポリシークラスと対応するEloquentモデルを記述する

(3) 作成したポリシーに認可する条件を記述する

(4) 作成したポリシーを適用したいアクションやミドルウェアに追加する

これで、ポリシーに記述した条件を満たしていないと、アクセスできない/できる みたいなことができる。この後、ブラウザからアクセスしてみて、403とかになれば良さそう。あと、ポリシーとは関係ないけど、ゲートを定義する際の名前の付け方について、

Gateは"誰が"、"何を", "どう", "できる/出来ない" を扱うもので、"誰が"はログインユーザーが第一引数から渡されることで自明なので "何を", "どう" が大切。なので名前の規則としてV-O (SVO) の形にしましょう。

っていうのがあって、名前のつけ方とかも重要なので気をつける。例えば、Adminユーザーだったら投稿できる。みたいなことを考えてみると、(canのFacadeを利用して書いてみることを考えると)、Admin can update Post になるのでupdate-post って感じで、Gate::defineに定義する。

Laravel 5.1でcanミドルウェアを使えるようにする

やったことは、laravel 5.7の Illuminate/Auth/Middleware/Authorize.php を、そのまま5.1のlaravelで独自ミドルウェアとして定義した。

(1)5.7環境で、Kernel.phpの$routeMiddlewareで定義されてる canミドルウェアで定義されてるAuthorizeクラスを確認

(2)それを、Authorizeを、5.1環境で独自ミドルウェアとして定義する

これで、routingにcanミドルウェアを使えるようになった。

ちょっと話が逸れるかもだけど、この作業してるときちょっと悩んだことについて書くと、Authorizeクラスを持ってくるとき、最初5.3から持ってきていて、それだとうまくいかなかった。それで色々やってて、5.7から持ってくるとうまくいった。これは、5.3から5.7の間でコードが変わってたからなんだけど、どう変わってたかというと、

5.6まではcan middlewareでユーザーがログインしているかをチェックしていた。 $this->auth->authenticate() . 5.6? 5.7? でcan middlewareはguestも受け付けるようになったのでログインしているかどうかはチェックしなくなったらしい。なのでcanでログインしてるかしていないかはチェックしないと思って使えば良いので5.7のコードで問題なさそう

めちゃめちゃ勉強になった。あと、githubの使い方で、ブランチ間の差分を見る方法もを知らなかったので、勉強になった。

Authorize.php 5.3と5.7の差分

github.com

Authorize.phphistory https://github.com/laravel/framework/commits/5.7/src/Illuminate/Auth/Middleware/Authorize.php

ルートパラメーターからミドルウェアインスタンスを渡せるようにした(モデル結合ルート)

ここまでやって、canミドルウェアを使えるようになったし、ポリシーも登録できたんだけど、特定のリソースにアクセスする際の認可をポリシーで、うまく書けていなかった。(例えば、自分が投稿したリソースだったら、アクセスできる。他の人はNG。みたいな認可の処理を書きたい)もう少しいうと、ルートパラメーターのidを元にしたリソースのインスタンスを、ポリシーで定義してる認可の条件で使えるようにしたいけど、どうやってやればいいかわからなかった。結果的には、ドキュメントのLaravel 5.1 HTTPルーティングのモデル結合ルートに書いてあることを定義すると、うまく渡せるようになった。(RouteServiceProvider::bootにモデル結合を定義する)

ドキュメント https://readouble.com/laravel/5.1/ja/routing.html#implicit-binding

これでうまくいったんだけど、ここまでくるのにいろいろと悩んでて、その辺りを書くと、canミドルウェアを使って、routingにポリシーを定義する方法がわからず、めちゃめちゃ悩んだ。今振り返ると、ドキュメントにちゃんと書いてあるんだけど、正しく読めていなかった。その際にやったこととしては、Authorize.phpの処理をxdebugでとめまくって、コードの深いところまで、追いまくって、どこの条件でおかしくなってるのか調べたりした。結果的には、やはりドキュメントに書いてある通りに定義されてなかった(引数の指定の仕方がおかしいなど)のが原因だったことがわかったんだけど、定義元ジャンプしまくって、コードを深く追いまくったおかげで、実際どういう処理が書かれてるのかを知れたので、すごく勉強になったと思う。(追ってる間のコード、ちゃんと読めてないのもあるかと思うので、もう少し読み解けるようなりたい。最後のあたりで make ってやつが出てきたりしたけど、よくわかってなくて、その辺り気になってる)

f:id:shimabukuromeg:20181202143121p:plain

まとめ、次やること

  • ポリシーとゲートに違いとか、Laravelで認可の処理書くの、基本的なとこだけど少し詳しくなれたと思う。
  • コードを追っていくやつ、もう少しやってみる。個人的に、ファサードとかDIとかサービスコンテナとかいまいちよくわかってなくて、コード追うやつやりながら、ドキュメントとか読んだりすると理解できそうな気がしてる。あんまりよくわかってないけど。

Laravel学習方法

最近laravel勉強してて、学習するのに重要だなあと思ったポイント備忘録。

  • xdebug
  • Laravelのソースコードを追う
  • Laravelの公式ドキュメント読む
  • PHPのドキュメント読む
  • Laravel本読む
  • 他のlaravelプロジェクトのソースを読む

qiita.com

特にxdebugで処理を止めながら、コードを深いところまで読んでみるってのが重要な気がしてて、そのあとにドキュメントを見ると、ドキュメントがかなり読みやすい感じがありました。それに加えて、Laravel本を参考に色々手を動かしてみるとか、ほかのLaravelプロジェクトを読むとかまで手を伸ばせたら良さそう。

最近 Laravelで学んでること

最近 Laravelでお仕事させてもらっていて、その中で学んだこと、疑問に思ったこと、調べてみたこと、コードレビューで指摘受けて気づけたことなどを書きます。Laravelでどういうことをやってるときの話なのかって部分をもう少しいうと、ざっくりですが「ユーザーを招待して登録する」みたいな機能を作ってる時の話。(書いてることは、あまり関係なさそう。とりあえず、最近やってることです。)

(1)Laravelでパスワードを二回入れて確認する confirmed validation

同じ値を確認用で2回入力する際のバリーデーションについて。パスワードじゃなくても、xxxx_confirmationフィールドでチェックしてくれる。Postする際の処理をのバリデーションをフォームリクエストに定義する。(フォームリクエストで、バリデーションを作るの、なぜかよく忘れてしまう)

公式ドキュメント バリデーション 5.5 Laravel

confirmed フィールドがそのフィールド名+_confirmationフィールドと同じ値であることをバリデートします。例えば、バリデーションするフィールドがpasswordであれば、同じ値のpassword_confirmationフィールドが入力に存在していなければなりません。

class StoreRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'password' => 'required|confirmed|max:60',
        ];
    }

    /**
     * 定義済みバリデーションルールのエラーメッセージ取得
     *
     * @return array
     */
    public function messages()
    {
        return [
            'password.required' => 'パスワードの入力は必須です',
            'password.confirmed' => 'パスワードが異なります',
        ];
    }
}

www.nyamucoro.com

(2)viewのデザインのために<br> 使ったら負け。bootstrapだと mt-2 mb-2 とかのmargin増やすutilityあるのでそれ使うと良い。

getbootstrap.com

(3)既にログイン済みだったら〇〇するって処理を、guest middleware(Laravel標準で準備されてるmiddleware)を参考にかく

ログイン済みかログイン済みじゃないかの場合で、処理を分けたいとき、例えば、ユーザー登録で、既にログイン済みだったら、〇〇へリダイレクトして欲しい、という処理が書きたい。Laravel標準で、認証済みかどうか判定し、認証済みの場合は/homeにリダイレクトする、guestというミドルウェアが用意されるので、これを参考にした。独自のミドルウェアを作るときは、

こういう流れだと思っているんだけど、Http/Kernel.phpに登録する、ルーティングに登録する、あたりをちゃんと整理できていないので、ミドルウェアについては、改めて整理したい。登録したミドルウェアをどの処理に適用させるのかっていうあたりを特に整理したい。

(4)コントローラー側のコードで、POSTの処理後に、viewを返すのか、redirectするのか、ちょっと悩んでる。

例えば、「ユーザー登録して、登録完了しました」というページを表示したい場合、POSTのリクエストを処理するアクションがviewを返してくれるように書くのか、完了しました表示してくれるページを返すアクションを別途作って、そこにリダイレクトしてくれる方が良いのかっていうところで悩んだ。今回は、POSTの処理で完了しましたのviewを返すようにしたけど、こういう部分で迷った場合の判断基準がわかっていないので、調べてみる。また、ちょっと話がずれるかもしれないけど、今回この処理を最初redirectするように書いていて、その場合に、例えば、POSTの処理で持っている情報(変数)をredirect先に引き継ぐには、どうしたら良いかってところですごく悩んだりした。sessionに投入して、取り出すみたいな感じでその場合はやったけど、sessionをむやみやたらに使うのはバグの温床なので慎重にしないといけないということだった。postの処理で使ったデータをそのままviewで使いたい場合に、postアクションでviewを返すようにするって感じなのかな。

(5)Sessionにデータを突っ込むのは慎重にする

sessionにデータを突っ込むのは慎重にしないとバグの温床になるので、注意する。バグの温床になる、理由をちゃんと理解できていない気がするので、この部分をもう少し勉強する。sessionに定義される変数を追うのが難しいというか、他の人がコード書くときに、sessionに変数が定義されてることを想定してコード書かないだろうから、影響する可能性があってあまりよくない、ってことかな?それで、sessionを使う場合については、flashを使って、次回1回切りでsessionにデータを突っ込むようにするのが良い(消えるのが保証されている)

例 e$request->session()->flash('user', $user);

公式ドキュメント HTTPセッション 5.5 Laravel

フラッシュデータ

次のリクエスト間だけセッションにアイテムを保存したいことは良くあります。flashメソッドを使ってください。flashメソッドは直後のHTTPリクエストの間だけセッションにデータを保存します。それ以降は削除されます。フラッシュデータは主にステータスメッセージなど継続しない情報に便利です。

(6)ランダムな値の生成方法

ググって見つけたやつ。メモ

substr(base64_encode(md5( mt_rand() )), 0, 30);

(7)Scope

where('xxx', 'yy') みたいに書いてるのを、モデル側でメソッド書くようにして、それを呼び出すようにして、コード読みやすい感じにする

(8)バリデーション(FormRequest)

バリデーションを書く場所いつもどこだっけってなるけど、基本的にPOSTのリクエストするときは、フォームリクエストを作ってバリデーションするようにする。

(9)self::creating データ登録時に自動的にデータを登録するようにする

Railsでいうbefore_createみたいなのを作る。(コントローラー側の責務を減らす)

qiita.com

qiita.com

qiita.com

まとめ

基本的なことばかりっぽいけど、すぐ忘れちゃうので、自分の理解の整理のために書いた。もっとちゃんと理解したいやつがまだまだあるので、次は以下の内容を整理したやつ書く。

  • フォームリクエストのバリデーションの理解を整理する
  • ミドルウェアの理解を整理する
  • 認可の処理についての理解を整理する