20190530のlaravelに関する記事は8件です。

Laravel-Eloquent(Mysql)で、select結果に固定値カラムを追加する方法(使用例)

mysql

select '1'  as sample;

Laravel

$list = SampleModel::select('id', DB::raw("'1'  as sample"))->get();

真偽値なんかを扱いたいときは

$list =SampleModel::select('id', DB::raw("1 = status  as sample"))->get();

trueは1が入り、falseの場合は0が入る。

どういったときに便利か

Sampleテーブルのカラムにstatusカラムが存在し、そのstatusの中身が1,2,3だった場合、1の時はこのボタンを表示したいんだけどなぁとか思ったときに、カラムを足さない場合は、

blade
@foreach($list as $item)
@if((int)$item->status === 1)

といったような文を書くことがあるとします。この形は、Viewのほうには、なるべくロジックを加えたくないし、1は何を示しているのかわかりません。そのために、SampleModelに定数を定義します。

SampleModel.php
const STATUS_HAPPY = 1;
const STATUS_SAD   = 2;

bladeを修正します。

blade
@if((int)$item->status === \App\Models\SampleModel::STATUS_HAPPY)

これで、statusがHappyの時は、なにかするんだなとわかりやすくなりましたが、if分の中が長くなってしまいました。そのため、データにstatusがhappyかどうかのフラグを持たせる処理を作ってみます。

$list = SampleModel::select('id', 'status')->map(function ($row){
            $row->is_happy = ((int)$row->status === SampleModel::STATUS_HAPPY);
        });
blade
@if($item->is_happy)

先ほどより、bladeのほうの処理は、短くなりよくなりました。ただ、phpの処理のほうをis_happyだけのために、mapを回したく無く感じますので、selectでとっちゃいます。

$list = SampleModel::select('id', 'status', DB::raw(SampleModel::STATUS_HAPPY. ' = status as is_happy'))->get();

これで、statusカラムの中身とSampleModel::STATUS_HAPPYが一致した場合はis_happyは1で、一致しない場合は0が入りますので、
bladeでそのまま使えます。

blade
@if($item->is_happy)

アクセサを使った書き方

ありがたいコメントをいただきましたので、追記させていただきます。
Laravelには、アクセサ(カラム定義)機能がありまして、getカラム名Attribute()で取得するカラムのフォーマットを定義したり、もともと存在しないカラムを追加することができます。

// SampleModel
public function getIsHappyAttribute() {
    return (int)$this->status === static::STATUS_HAPPY;
}

// controller
$list = SampleModel::select(['id', 'status'])->get();

// blade
@foreach ($list as $item)
@if ($item->is_happy)

注意点としましては、SampleModel::select(['id', 'status'])->get()をforeachで回した際は、is_happyは取得できますが、toArray()を使ってしまうと、is_happyを取得できなくなります。

まとめ

アクセサを使う方法が1番、それでもダメな特殊ケースの場合のみ、DB::rawを使って、カラムを付け加える方針で今後やってこうと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 2つの異なるテーブルを合わせて、ページネーションをかける

Apple・Lemonテーブル

public function test(Request $request)
{
    $subQuery = Apple::from('apples as A')
        ->select('A.id', 'A.name');

    $list = Lemon::from('lemons as L')
        ->select('L.id', 'L.name')
        ->UnionAll($subQuery)
        ->orderBy('name', 'asc')
        ->paginate(10);

    return view('test',
        [
            'paginate' => $list,
        ]
    );
}

unionは、重複を削除します。UnionAllは重複を削除しません。
union allコストについて参考記事

異なるDBを見たい場合

public function test(Request $request)
{
    $subQuery = Apple::from('sample1.apples as A')
        ->select('A.id', 'A.name');

    $list = Lemon::from('sample2.lemons as L')
        ->select('L.id', 'L.name')
        ->UnionAll($subQuery)
        ->orderBy('name', 'asc')
        ->paginate(10);

    return view('test',
        [
            'paginate' => $list,
        ]
    );
}

テーブルの前にDB名.で指定すると別々のDBを見に行ってくれます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Excel で .xlsx ファイル出力時にデフォルトのフォントを変更する方法

Laravel Excel https://laravel-excel.com/ を使って、 .xlsx ファイルを出力する際にファイル全体のデフォルトのフォント変更する方法。

なお、 Laravel Excel のバージョンは 3.1 です。

結論: registerEvents() を使って、 $event->sheet->getDelegate()->getParent()->getDefaultStyle()->getFont()->setName('MS Pゴシック'); とかする

書いたとおりなのですが、 registerEvents() を使って、 $event->sheet->getDelegate()->getParent()->getDefaultStyle()->getFont()->setName('MS Pゴシック'); などとします。

どうやるのか

https://docs.laravel-excel.com/3.1/exports/

このチュートリアルに習って、 UsersExport を生成すると以下のファイルが生成されます。

app/Exports/UserExport.php

で、そのファイルの中は、以下のようになっているはずです。

app/Exports/UserExport.php
<?php

namespace App\Exports;

use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;

class UsersExport implements FromCollection
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        return User::all();
    }
}

このクラスに Maatwebsite\Excel\Concerns\WithEvents を implements して、要求される public function registerEvents(): array; を実装します。

https://docs.laravel-excel.com/3.1/architecture/#lifecyclehttps://docs.laravel-excel.com/3.1/exports/extending.html#events を参照のこと。

app/Exports/UserExport.php
<?php

namespace App\Exports;

use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithEvents;

class UsersExport implements FromCollection, WithEvents
{
    /**
    * @return \Illuminate\Support\Collection
    */
    public function collection()
    {
        return User::all();
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function (AfterSheet $event) {
                $event->sheet->getDelegate()->getParent()->getDefaultStyle()->getFont()->setName('MS Pゴシック');
            },
        ];
    }
}

で、上記のように、 PhpSpreadsheet のインスタンスを引っ張り出してきて、 最終的に setName(); します。

フォントサイズを変更したいときは、同様に setSize(); です。

PhpSpreadsheet で設定できるやつは、この方法で設定できるはず。 https://phpspreadsheet.readthedocs.io/en/latest/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2上でCannot create cache directory

私の場合はEC2上でcomposer iを実行すると発生。
権限がなさそう。

Cannot create cache directory /home/ec2-user/.cache/composer/repo/https---repo.packagist.org/, or directory is not writable. Proceeding without cache
Cannot create cache directory /home/ec2-user/.cache/composer/files/, or directory is not writable. Proceeding without cache

/home/ec2-user/.cache/composer/composerは環境によるので注意

同じ現象。
Cannot create cache directory .. or directory is not writable. Proceeding without cache in Laravel Ask Question
Cannot create cache directory in Laravel

ディレクトリの所有権を変更。
※環境に(ry

sudo chown -R ec2-user /home/ec2-user/.cache/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

駆け出しエンジニアのオリジナルアプリ開発備忘録

はじめに

この記事は、駆け出しエンジニアがオリジナルアプリの開発を通して学んだことを備忘録としてまとめ、一応他人に向けて書いてる風な記事となっております。
ついでに開発における手順も書いておきます。

アプリ開発を通して気づいた改善点

まず自分が開発を通して気づいた改善点から残します。

  • 開発は設計8割コーディング2割だと思え
  • アプリ開発の目的を明確にしろ
  • コアな機能を一つ決めろ
  • 浮気するな、初めに決めたものをまずは作れ
  • デザインとかレスポンシブは後でやれ
  • Negativityから距離を置け

全部一人で開発をしてみて感じたこと学んだこと

思ったままに書きます。長いので、見たい方だけ見てください。
今回はPHP x Laravelという組み合わせで、初めて誰の手も借りずに(検索は別)自力で0からアプリを開発しました。
開発も含めてPHP歴は49日。開発にかけた日数は計25日で1日の開発時間を平均すると約5時間ほどだったかと思います。

こちらが今回開発した自己管理アプリです。
http://grower4u.herokuapp.com/
目標とタスクを立てて、進捗管理ができます。

負よりな話

全体を通しての印象は、開発にものすごく時間がかかってしまったということ。
原因は大きく分けて3つ。

  • 1つ目は設計が中途半端のまま開発に入ったこと。
  • 2つ目は開発手順が決まっていなかったこと。
  • 3つ目はモチベーション管理の部分。

設計が中途半端のまま開発に入ったこと

自分は設計をするのがもどかしく、早くアプリを作りたかったので、なんとなくのイメージを紙に書き出してからすぐ開発に入りました。
なので、機能実装の構想と開発を同時並行的にしていました。これの何が悪いかというと、ゴールが定まっていないので、無駄な作業が格段に増えるということです。
こんな機能あったらいいな、実装してみよう!とつい浮気をしたくなります。
実装してみて良し悪しがわかり、実際に学べることももちろん多いけれど、アプリ開発をする上での自分の目的がなんなのかを軸に優先順位を決めないといけません。

開発手順が決まっていなかったこと

これも設計を怠ったことによる副作用といってよいかもしれない。
気になったところから開発に着手していたので、当然効率は悪い。必要な機能はそっちのけで、気になった細かい部分の修正をしたりしていました。
全く愚かな行為と言ってよいです。完璧主義が出ちゃいました。少しはほっといて、本当に大事な部分の開発からまず着手すべきです。

モチベーション管理の部分

1日平均約5時間と言いましたが、5時間中4時間59分をPCの前で
ぼーっとして過ごした日もあります。1分はPCの立ち上げですね。笑
スクールとか、プログラミングに触れている人と話していると、時々、「モチベーションを言い訳にしてる奴はその時点でダメ、プログラミングやめたほうがいい」という方が意外にも結構いたりします。
気持ちはわからないでもないですが、絶対そうとも言い切れません。自分たちはコンピューターではなく人間で、感情があり、感情によるパフォーマンスへの影響力はとても強大です。

個人差ありありですが、自分の場合は海を越えた遠距離関係にある彼女とたびたび喧嘩をし、よくメンタルやられてました。(簡単に会えないのがキツイ)
理由は人それぞれですが、モチベーションがなかなか保てない場合は、自分の開発について誰かと楽しく話してみたり、ストレス発散の時間を無駄と思わずにあえて取ったりしてみるのが良いと思います。
完成後の楽しいイメージが湧いてくると、自然とやる気になれるかもしれません。
モチベーションを上げるのも大事だけれど、下げないことも大事です。
とにかくモチベを下げる要因からはなるべく離れましょう。

正よりな話

反省点ばかり並べましたが、学びの方が多かったのは事実です。

オリジナルアプリ開発のメリット

  • 開発の楽しさを再認識
  • プログラミング力がつく
  • 客観的に考える力がつく
  • 検索力がつく
  • 忍耐力がつく
  • 計画力がつく
  • 自信がつく
  • 自己解決力がつく
  • 行動の結果がすぐ目に見える

あげるとキリないですがこんな感じでしょうか。

まずは、開発はやはり楽しいなとわかります。自由に作れるって想像以上に面白いです。
そして当然のことながらプログラミング力がつきます。オリジナルアプリの開発は、基本的に自分一人で取り組みます。
想像以上に多くのエラーにぶち当たり、Qiitaやブログ、ドキュメント等を読み漁って解決策を模索することになります。
初めのうちはエラー画面を見るだけで幻滅することはいくらでもあり得るでしょう。

自分の場合、環境構築で8時間も足止め食らったり、ドキュメントにたどり着いても読み方がわからなかったり、フォーム一つの機能実装に2時間以上平気でかかったりといくらでもありました。エラー画面の出会いなんて100回は優に超えてたと思います(盛ってるかもしれないけど気分的には本当にそんな感じ)。

しかしこのエラーを乗り越えるための道中がまさに成長の一瞬一瞬で、解決すると喜びのアドレナリンが吹き出し、自信が少しずつつきます。最初は魔法のようなエラー文も、数をこなすと解読ができるようになってきます。そして同時に、エラーへの耐性がつき、エラーの出現によって萎えることも減っていきます。
この過程を通して自己解決力にも非常に磨きがかかります。全部一人ですから。
プログラミングの能力だけではなく、人間力も磨かれていきます。
アプリ開発は
アウトプットの連続`なのです。やらない手はありません。

そして、ここまでいくつもの修羅場を越えて出来上がった、
自分の最高傑作のアプリを見てみるとだいたいショボいというおまけ付き。笑
つまりまだまだ成長できるということであり、今以上に成長したらこの先どんな世界が待っているんだど、
ワクワクしかないわけです。ドラゴンボールの悟空気分ですね。

たくさん考え、たくさん手を動かし、プログラミングだけでなく人間力も磨いていきたいですね。

なので、初めから全てを上手にやろうとせずとにかく手を動かし、経験値を積み上げていきましょう。


オリジナルアプリの開発手順

開発前

開発アプリのアイデアを出す。

アイデアの出し方

ターゲットを絞って絞る

エンジニアの中でも駆け出しのエンジニアの課題に取り組もう

身近な問題に目を向けてみる

服買うの面倒だけど、自分に似合うかっこいい、カワイイ服が欲しい
→ 他の人に自分の服を選らんでもらえるwebサービス

アイデアとアイデアを合体してみる

共有 x 写真 = Instagram
共有 x 日常 = blog、Twitter
共有 x ストレス = なんかカオスなアプリ

コアな機能を一つ明確に絞る

アイデアを考え始めるとつい楽しくて、機能をあれもこれもつけたくなってしまう。
目的は、たくさんの機能をつけることではなく、サービスを通じて課題を解決すること。
まずはコアな機能を一つ絞り、それに全力を注ぐ。

アプリのデザインを設計

デザインの決め方

既存のアプリやウェブサイトを実際に見てみるのが一番早い。
探すと色々面白いものがある。
https://muuuuu.org/

ペーパープロトタイプを作成

紙とペンを用意する。
書くページの見た目を実際に紙に書き出す。
ボタンや画像の配置も忘れずに。

DBのテーブル設計

情報を洗い出す

例、Twitter
ユーザーの情報
ツイートの情報
コメントの情報

情報を整理する

リレーション

ユーザーは複数のツイートを持ってる。
コメントはどれかのツイートに属している、など

カラム

ツイートはつぶやきの内容、画像、投稿時間を表示する
→ つぶやきのカラム、画像のカラム、投稿時間のカラム

後に変更があった場合も対応できる冗長性・拡張性を意識する。
仮にユーザーにコメントカラムがあると、ユーザーは1つのコメントしか持つことができない。
よって、コメントはコメントのテーブルを用意し、ユーザーが複数のコメントを持てるような設計が必要。

ここまでちゃんとできれば開発の8割が完成したようなもの。
それくらいの気持ちでやる。

開発スタート

Git管理

何が何でもブランチを切って機能実装ごとにコミットして、開発をしっかりと管理しましょう。
これは死守です。初めはgitコマンドすらわけわからないかもしれませんが、
数をこなして慣れていくしかありません。

DB設計

モデルとマイグレーションファイルを作成。
開発前に整理したDBの設計を元に、テーブルを光速で作る。
アソシエーションを組む
あとで修正できるからスピード意識

ビュー→ルーティング→コントローラー→ビュー

投稿機能を例にすると、
投稿のためのビューファイルを作成し、フォームだけ用意する。
ルーティングを記述する。
アクションを記述する。
データが保存されているかDBを確認する。

これを機能ごとに中身だけ変えて繰り返す。

デザイン設計

全ての機能の実装が終わったら、デザインの設計をする。
まずは、初めにペーパープロトタイプに落とし込んだ設計に忠実に作る。
ここで、見た目こっちの方がいいなー、とか、
ここにこんな機能あったらいいなー、とか思ってしまうかもしれないが、
こらえて、まずは何が何でも忠実に最初のものを貫きます。

デプロイする

一通りできたらデプロイする。
ここまでくるとやっと終わった感があるが、デプロイ時やデプロイ後にバグが出たり、
画像が表示できないなど、普通に萎えるようなことが起き得ます。
気を抜かずにとりあえずデプロイしましょう。

開発後

アプリを公開

SNSや友達、家族にアプリを公開する。
人に使ってもらうためのサービスを作っているのだから、
どれだけ酷いアプリでもまずは人に知ってもらい、さらに良ければ使ってもらう段階までいきましょう。

使ってみた感想が聞けたら成長のチャンス。ユーザーの素直な感想は次回の開発にとても役立つ。

修正点をストック

気になる部分、修正したい部分をストックしておく。

修正 or 新たなアプリ開発

アプリの開発から公開までを通じて得た学び、を現在のアプリに活かすか、
新しいアプリ開発に反映させましょう。

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2上でNo space left on device

私の場合はEC2上でcomposer iを実行するとNo space left on deviceがでた。
空容量がないらしい。

解決

ディスクの容量を確認

$ df -h

ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         476M     0  476M    0% /dev
tmpfs            493M     0  493M    0% /dev/shm
tmpfs            493M  784K  493M    1% /run
tmpfs            493M     0  493M    0% /sys/fs/cgroup
/dev/xvda1       8.0G  7.9G    0G   99% /
tmpfs             99M     0   99M    0% /run/user/0
tmpfs             99M     0   99M    0% /run/user/1000

確かにダメそう

/dev/xvda1       8.0G  7.9G    0G   99% /

/tmp内の不要ファイルを削除したら30%になり、エラーは解決できた。
(rubyのインストールを何度も失敗してゴミが大量にあった)

自分の環境だといらないファイルを削除したら解決したが、インスタンス再起動で解決する模様。
EC2 instance on Amazon and I am greeted with “No space left on the disk

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

bladeで"syntax error, unexpected end of file"に少し泣かされた

bladeで「syntax error, unexpected end of file」というエラーが出たので、
ファイルの最後の方をいろいろ見ていましたが、見当違いでした。

原因は、
@elseなどのブレード構文の前後に半角スペースを入れず、
@if(a>b)ほげ@elseふが@endif
などと そのまま文章をつなげていたことでした。

適切にスペースを挿入してやると、
正しくif文などが評価され、エラー解消。

原因究明に少しだけ時間を食われたので、ここにメモいたします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravelでURLを作成する便利な関数(route()・action())いいなーと思っていたら、はまった話

route()・action()はどちらもURLを作成するときにすごく便利です。

route('sample.index');  //こちらは、routes/web.phpでnameを指定する必要があります。
action('SampleController@index');

どちらも同様のURLを作成してくれます。第二引数で、パラメータを渡すことができます。
Bladeのほうで、利用するときは、旧型の書き方と比べると可読性が全然違います。

旧型

{{Form::open(['url' => 'http://sample/index?id='. $data['id']. '&name='. $data['name'])}}

route()・action()利用時

url属性を使用した場合

{{Form::open(['url' => route('sample.index', [$data])])}}
{{Form::open(['url' => action('SampleController@index', [$data])])}}

LaravelのBladeには、routeとactionの属性が用意されています(パラメータがない場合は利用する)
(こちらの形でも、input hiddenを使えば、パラメータを渡すことは可能ですが、個人的には、すべてurl属性を使って統一するほうが見やすい気がします。)

{{Form::open(['route' => 'sample.index'])}}
{{Form::open(['action' => 'SampleController@index])}}

Formにroute関数を使用して、特定の場合、思った挙動をしなくなる話

当然と言われれば、それまでの話なのですが、URLにidを埋め込んで、そのidに、/を入れたときに、思った通りの挙動をしません。例をあげてみます。

routes/web.php
Route::get('/test/{id}/index', 'TestController@index')->name('test.index');

idごとのデータのindexメソッドの処理がはしる想定のルートです。

TestController.php
public function index(Request $request, $id)
    {
        dd($id);
    }

引数で、idを受け取ります。それでは、bladeを編集します。

test.blade.php
{{Form::open(['url' => route('test.index', ['id' => '1']), 'method' => 'get'])}}
{{Form::submit('送信')}}
{{Form::close()}}

まずは、idに1をいれて、ボタンを押下してみます。

Screenshot_8.png

想定通り、1が表示されました。それでは、/をいれてみます。

test.blade.php
{{Form::open(['url' => route('test.index', ['id' => '/']), 'method' => 'get'])}}
{{Form::submit('送信')}}
{{Form::close()}}

/を入れて試してみます。404エラーがでました。URLをみると、///となっており、URLがおかしくなっています。

Screenshot_10.png

対処法

本来、/はURLの区切り、?はパラメータを渡すときにURLの大切な役を担っています。それを、URLのパラメータとして使用するためには、エンコードする必要があります。

routes/web.php
Route::get('/test/{id}/index', 'TestController@index')->name('test.index')->where('id', '(.*)');

Screenshot_11.png

できました。?をパラメータに使いたい場合は、エンコードされていたらそのまま使えますが、されていなかったら、urlencode('?')などでエンコードしてから、パラメータとして使用しましょう。

まとめ

パラメータに/や?を使わないようするのが一番いいと思います

参考にさせていただいた記事-スラッシュのエンコード

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む