エンジニアのひよこ_level10

毎日更新してた人。たまに記事書きます。

【Laravel】データベースから日付データ取ったら、文字列でデータが来た時の対応【426日目】

モデルの時間を取ろうとしたら、文字列・・・

    User::where('id', 5)->start_at->gte(Carbon::now());

usersテーブルの日付データを使って、時間の比較をしようとしたら、 start_atが文字って言われた(T_T)

どうせなら、日付データはCarbonとかで取ってきてほしい!!!

Userモデルクラスに、datesを書く

class User extends Model {
    protected $dates   = ['start_at', 'end_at'];
}

このように、該当するモデルクラスに、 dates変数を定義して、日付データのカラム名を入れる。

これだけで良い!

どうなるの

$datesで指定したカラムは、戻り値がCarbonになって返ってきます!

なので、スムーズに日付の比較が出来ます。これなら最初のコードも動きます。

あ、もちろんですけど、ちゃんと元のカラムのデータは日付データにしてくださいね。datetimeとか。

お疲れ様でした。

【日記】Laravelアドベントカレンダー書いた感想。【425日目】

日記。

Laravelアドベントカレンダー書きました。

www.nyamucoro.com

どうだった?

とりあえず、いつもどおりの記事です。

コントリビュート系のネタでやろうと決めていましたが、
最近見つけたorderByの仕様がいい感じにわかりやすく、面白いネタだった気がします。

日頃の勉強の積み重ね、やっぱり大切ですね。

去年と比べて

実は、去年もアドベントカレンダー書いていたんです。ちょうど同じ日に。

www.nyamucoro.com

全く役にたたない・・・w

でも、精一杯だったんです。その頃と比べたら、結構成長できてるんじゃないかな?って思いました。

自分の成長に気がつけるのも、こうやってアウトプット続けていたからですね。

意外だったこと

これ、エラーになるが多いとは思っていましたが、descになるという回答者も多め。

自分の友人には答えを教えていましたが、それ以外に誰が投票したんだろう。
どうやって気がついたか、結構気になりますね。

まあ、こういうの一番ありえないのが回答だ!ってメタ読みもできますが・・・w

最後に

みんなもアドベントカレンダー挑戦してほしいな。

アウトプット大切。

こういう機会に飛び込むのが、アウトプットするいい機会だと思うのです!ぜひぜひ!

あと、Laravelは元コードも読んでみてね!

【Laravel】初心者も出来た!Laravelの中身を読んでコントリビュートしよう

Laravelアドベントカレンダー12日目の記事です

この記事は、Laravelアドベントカレンダー2018の12日目の記事です。

qiita.com

読者対象

PHP、Laravel初心者。

Laravelにプルリク出してみたい人。

初心者PHPerです!

はい!私PHP歴1.5年の初心者です!

そんな私も、実はLaravelにプルリクエストを出して、コントリビュートした経験が。
バグを直しました。

[5.7] causes problem when we write unit-test in `cache('foo')` by klack710 · Pull Request #25492 · laravel/framework · GitHub

実は、Laravelにプルリクを出すって、そんなに難しくない!
この記事をきっかけに、それを知っていただけると嬉しいです!

突然ですが問題です

User::select('*')->orderBy('id', 'ascc')->get();

このコード、'asc'を間違えて、'ascc'になってますね。

これはどう動くでしょうか!

1. そのまま
2. エラーになる
3. ascになる
4. descになる

他の人の回答

Twitterのアンケート。中身を読む前にぽちっとしてみてください。
他の人の意見も見れます。

1. Laravelのコードの場所

Laravelのプロジェクトの中にある、vendorディレクトリを開いたら、 laravelって文字が見えますね。それです。

vendor/laravel/framework/src/Illuminateの中が主に見るコードです。

2.クエリビルダの場所

vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php

ここが、クエリビルダのコードが書かれている場所です。

Database、Query、Builder、わかりやすいですね!

3.関数を探す

では検索をしてみましょう。 orderBy(で検索してみてください。

みなさん、読みましたか?では正解です。

(回答)5.7現在、descに変わります

    public function orderBy($column, $direction = 'asc')
    {
        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [
            'column' => $column,
            'direction' => strtolower($direction) === 'asc' ? 'asc' : 'desc',
        ];

        return $this;
    }

これ、PHP初心者でも読めますね!

解説

'direction' => strtolower($direction) === 'asc' ? 'asc' : 'desc',

strtolowerは、$directionをすべて小文字にします。

なので、$directionが'asc'、'ASC'、'Asc'とかなら、'asc'で動きます。

それ以外はすべて'desc'で動きます。

'ascc'は条件に合致しないので、'desc'で動く。
そう、さっきの問題は5が正解です!

元コードを読むのは意外と簡単

今回はファイルの場所を私が示しましたが、
自分で探すのも簡単です。

よくコードの一番上に useを書くと思います。プロジェクトでも探してみてください。

use Illuminate\Database\Eloquent\Builder;

Illuminateで始まるuseです。

このパスはLaravelのコードのことです。
vendor/laravel/framework/src/の下にあるこのパスを辿れば、元コードにたどり着きます。

namespaceやuseに着目すれば、元コードは簡単にたどれます!

コントリビュートの話は?

さっきの問題が予想外だった方、このままでいいのかな?とか思いませんでしたか?
エラー吐くべき?似たコードは保管するべき?とかとか。

そんなときが、コントリビュートチャンス。

私がこの話したら、早速友人がissueを立てました。

Add InvalidArgumentException For orderBy() in Illuminate\Database\Query\Builder · Issue #1434 · laravel/ideas · GitHub

さっきコード読んだとき、結構簡単なコードだと思いませんでしたか?
コントリビュートって結構難しくないのです。

5.7では'desc'で動くと書きましたが、これがもしかしたら、明日にでも修正されるかもしれない!
私も、バグ修正はプルリク出して1日でマージされました。

コントリビュートは難しくない!

私がバグを直したときも、if文を少し追加したものでした。
(マージしてもらったあとで、コードをもっと良いコードに変えてもらいましたが、テストコードは残ってます)

[5.7] causes problem when we write unit-test in `cache('foo')` by klack710 · Pull Request #25492 · laravel/framework · GitHub

ぜひ、Laravelで『あれ?』って思ったときは、一度コードを読んでみてください。

そして、プルリクを出してみてください。

『大型OSS、Laravelにコントリビュートした!』『俺のコードが世界中で動いている!』

ちょっと冗談めいた話ですが、それができるのが、この業界の面白いところ。
ぜひ、元コードを読んで見る習慣をつけてみてください。

Laravelはよくできたコードなので、普通に勉強になると思います!

是非皆さんもコードを読んでみてください!

おまけ

コントリビュートの過程や、コントリビュートでどんな面白いことがあったかは、以下の記事に書いています。
コントリビュートすると何が嬉しい?ってのは、この記事を参考にどうぞ。

いい記事だと思ったら、是非下のTwitterFacebookでのシェアボタンでシェアをお願いいたします!

www.nyamucoro.com

【メモ】Controller、Service、Repositoryの分け方の考え方の一つ【424日目】

プログラムの役割を分ける

コードを書いていて、各コードの役割はきっちり分けたい。

やってることごっちゃごっちゃになったらコード読むの大変だしね。

ただ、その時に分け方もあやふやだと、結局ごちゃごちゃしたコードになって意味がない。

ということで、定義をしっかり考えたい。

フォロワーさんがアドバイスくれました。

ってことで、頂いたアドバイス

どういうこと?

Controller

Controllerでは、ユーザーがFormとかで入力して来た値を、いい感じに変換する。

例えば、数値をもらいたいのに、数字の文字列が来たりとかいろいろありますよね。

それらを変換したり、一部だけを切り抜いて、Serviceに引数として与えてやる。

$this->user_service->xxxFunc($request['number']);

Repository

データの永続化。つまり、データベースとかにデータを保存することとかをやる。

あるいは、永続化したものを取り出したりとか。

このとき、toArrayとかで変形しちゃだめだよ。あくまで、値を取ってくるだけ。

Laravelなら、モデルクラスか、それが入ったコレクションがそのまま取ってこれる状態。

return $this->user->all();

Service

データの永続化に関わらないところ。

メール送信したり、データ加工したり等々。

この後、戻り値でControllerに値を渡したりするわけなので、returnではいい感じの値にしてあげようね。

定義を意識しよう

ちゃんと、一貫して書けば、定義がごっちゃごっちゃにならないはず。

でも、定義の仕方間違えたな・・・って思ったら、いい感じにリファクタリング頑張ろう。

リファクタリング、どこかでしないと、あとでつらい思いをするのは、自分自身でもあるし、自分だけでは収まらないよ・・・!

【phpunit】同じテストコードをコピペしない工夫、dataProvider【423日目】

コピペでテスト書いてませんか

よくあるのが、入力を変えると、結果が変わるというテスト。

元コード

function testFunc($data)
{
....
}

テストコード

function testFunc_いろいろ返ってくる()
{
    $data = true;
    $expected = [1,2,3],

    .....


    $this->assertSame($expected, $result);
}


function testFunc_空っぽ()
{
    $data = false;
    $expected = [],

    .....


    $this->assertSame($expected, $result);
}

他コピペでdataとexpectedを変えていく・・・

こういうのもったいない。

入力と結果を関数で渡すdataProvider

こんなときに、$dataや$expectedを関数で渡してみよう

/**
  * @test
  * @dataProvider testDataProvider
  */
function testFunc($data, $expected)
{
    .....


    $this->assertSame($expected, $result);
}


function testDataProvider()
{
    return [
        'いろいろ返ってくる' => [
            'data' => true,
            'expected' => [1,2,3]
        ],
        '空っぽ' => [
            'data' => false,
            'expected' => []
        ]
    ];
}

何してるの?

テストのコメント欄に、 @dataProviderと関数名を書くと、
引数に値を入れることが出来る。

testDataProviderで配列を渡してやると、それをいい感じにテストしてくれる。
この場合、dataがtrueのときと、falseのときのテストが動く。

それぞれexpectedには、対応するdataが使われるので、見やすい!そしてコピペいらず!

ちなみに、キーに'空っぽ'とか日本語入れてますが、エラーが出たら、このキー名が表示されます。

めっちゃわかりやすい・・・!

参考になりそうなコード

github.com

クリックしたら、該当のコードに移ります。

ぜひdataProvider使って、コピペ減らして見やすいテストコードを!

【一週間振り返り】お仕事がんばった一週間でした【422日目】

1.今週一週間の感想(ざっくり)

お仕事がんばりました。

2.良かったこと

1.体調崩しつつも、お仕事頑張れた

3.もっとこうしたかったこと

体調崩してしまったこと・・・

やっぱり、体調大切。最近空気悪いのと、気温差がやばい。

体調崩したのとお仕事忙しくて、やっぱりニコ生の安定は難しい。

4.新しく気づいたこと

やっぱり、体調崩すとやれること減る。時間が失われる。

5.来週したいこと

OCRの勉強忘れてたけど、優先度低めなので、チケットは残そう。

自サイトの更新したいー!

6.その他

一週間単位で振り返るのやっぱり良さげ。

あと、Amazon Fire買ったので、どっかでレビュー記事書いてみたい

【個人サイト制作記3】Laravelのbladeでページのパーツを分けよう【421日目】

ブログのパーツを分けていこう

f:id:willow710kut:20181208211300p:plain

画像の感じだと、画面の上の方の黒いバー、これが使い回されているのがわかる。

ってことで、Laravelのbladeで、いい感じに使い回されるように書いてみよう。

パーツを分けよう

  1. ベースとなるすべてで使うパーツ(タイトルとか。)
  2. 黒いナビゲーションバー
  3. コンテンツ

ベース-(継承)->コンテンツ-(流用)->ナビゲーション

これで、コンテンツでナビゲーションを呼び出すので、ナビゲーションファイルは一つでよき。

ベースパーツ

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    @include('layouts._ga_tag')
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>@yield('title')</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    @yield('add_head')
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
            @yield('nav')
        </nav>
        <div class="pt-5">
            <main class="py-2">
                @yield('content')
            </main>
        </div>
        <footer class="container">
            @include('layouts._footer')
        </footer>
    </div>
    @yield('add_before_end_of_body')
</body>
</html>

こんな感じ。

@includeで、他のファイルを読み込んで、突っ込む。

@yieldの部分は、継承したときに、中に突っ込める。

この場合、コンテンツの方が、このレイアウトを継承して、そこにコンテンツを入れる。
ファイル見るほうが早いかも

コンテンツ

@extends('layouts._default')

@section('title')
throw new NoOutputException
@endsection

@section('nav')
// ナビゲーションバーをここで読み込ませる
@include('layouts._nav', ['active' => 'top'])
@endsection


@section('content')
//ここらへんでいろいろコンテンツを切り替える。
@endsection

extendsで上に書いたコードを読み込み、sectionでyieldに代入する。

こうすることで、毎回レイアウトをextendsすれば、毎回metaタグ書かなくてもいいし、ナビゲーションバーも流用できます。

再利用しよう

コピペが多いな?って思ったら、どんどん切り分けして、再利用できるようにしよー!

【個人サイト制作記2】Bootstrapを使って簡単TOPページ【420日目】

この記事はなに?

個人サイトを作るときになにをしたかを書いてるよ。

似た手順を踏めば、いつか私のサイトと似たレベルなら作れるかも?

前回

GCPでいろいろ頑張った

www.nyamucoro.com

今回のゴール

前回でLaravelのTOPページが出たので、

f:id:willow710kut:20181207212859p:plain

ここまで。

何をしたか

1.bootstrap公式サイトから、サンプルをダウンロード

ここのSource filesのダウンロードを選択

Download · Bootstrap

2.ファイルを解凍

3.良さげなサンプル探す

Examples · Bootstrap

4.サンプルのコードをコピペ

⁨bootstrap-4.1.3⁩/⁨site⁩/⁨docs⁩/⁨4.1⁩/⁨examples⁩/

サンプルページのコードがあるので、任意のbladeにコピペ(私は⁨jumbotron⁩を使いました)

5.サンプルと同じ画面が出たら、文字を直接bladeに打ち込む

(まだ動的にしない。それはまた今度)

どうだった?

いきなりサイトを動的にすると、ハードル上がるので、静的にしたのはよし。

サンプルを使うと、一瞬でいい感じになるね。

ここから、テーマを探したり、人によってはテンプレを探しても良いかも。
ただ、この経験しないでいきなりテンプレ探すとハマりそうなので、一度公式を使うのもありかもね。

お疲れ様でした!