Laravel シンボリックリンクで少しハマった話

##はじめに
今回はアップロードした画像をHomesteadで表示する時にハマった話です。
画像アップロード時のディレクトリ指定&リネームの仕方含めて備忘録という形で書いていきます。画像のアップロード方法自体の説明はしません。

参考：https://readouble.com/laravel/6.x/ja/filesystem.html

###環境
```
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G2022

ホスティングサービス: GitHub
通信プロトコル: SSH通信
```

***
##1.画像アップロード時のディレクトリ指定&リネーム
storeAsメソッドを使います。
###storeAsメソッドの使い方

```
storeAs(第一引数,第二引数);
#第一引数はディレクトリを指定します。通常は'public'を指定することで、 
 /storage/app/public/にファイルが保存されるようになります。
#第二引数はファイル名を指定します。

```
###実装
`storeAs()`を実際に使って実装していきます。今回はPostモデルのindexを参照して名前をつけます。(例)postのidが1の時は1.pngのように名前をつけます。拡張子指定方法は順次書いていきます。

```
$post_count = (string) Post::count() + 1;  

$file_ex = $request->file('image')->getClientOriginalExtension();

$post->image = $request->file('image')->storeAs('public',　$post_count.'.'.$file_ex);
```
postsテーブルのindex+1を取得し`string`型にキャストしています。
`getClientOriginalExtenstion()`でファイルの拡張子を取得します。
最後に`storeAs()`で`public`ディレクトリに`index+1.拡張子`という名前で保存できます。


##2.シンボリックリンク
###画像表示(失敗1)
次にアップロードしたファイル(画像)をHomesteadで表示していきます。既にマッピングは完了している前提になります。

```blade.php
<img src="/storage/app/public/{{ $post->image }}">
```
で表示できると思ったのですが、うまくいきません。少し調べてみると、Laravelは基本的に画像やCSSファイルの読み込みは`/public`ディレクトリで表示させる見たいです。しかし、`storeAs()`で`public`を指定して、ファイル読み込みでは`/public`で行うなんて無理じゃないか？と思ったのでさらに調べていくと、シンボリックリンクというものをするようです。早速やっていきます。

###シンボリックリンクする

```terminal
$cd /public
$php artisan storage:link

```
実行する事で、`/public`にstorageディレクトリが現れ、アクセスできるようになりました。※ショートカットのようなもの

###画像表示(失敗2)
これで画像表示の準備が整いました。早速ファイルパスを編集していきます。

```blade.php
<img src="{{ asset('/storage/app/'.$post->image) }}">
```
今回は`asset()`を使っていきます。使い方は省略します。これでシンボリックリンクもしたので表示されるはず・・・できませんでした。ここからがかなり詰まってしまったポイントになります。

###Homesteadでシンボリック
今まで忘れていましたが、Homesteadでwebブラウザに表示しているので、Homesteadのディレクトリ構成でシンボリックが行われているか確認してみます。

```terminal
$vagrant ssh
$cd アプリディレクトリ/public
$ls -la
total 20
drwxr-xr-x 1 vagrant vagrant  416 Mar  2 09:45 .
drwxr-xr-x 1 vagrant vagrant 1120 Mar  1 11:21 ..
drwxr-xr-x 1 vagrant vagrant  128 Mar  1 11:21 css
-rw-r--r-- 1 vagrant vagrant    0 Dec 16 10:35 favicon.ico
drwxr-xr-x 1 vagrant vagrant   96 Feb  6 12:45 fonts
-rw-r--r-- 1 vagrant vagrant  593 Dec 16 10:35 .htaccess
-rw-r--r-- 1 vagrant vagrant 1823 Feb 17 12:18 index.php
drwxr-xr-x 1 vagrant vagrant   96 Feb  6 12:45 js
-rw-r--r-- 1 vagrant vagrant   71 Feb 25 12:35 mix-manifest.json
drwxr-xr-x 1 vagrant vagrant   64 Feb 16 02:50 post_img
-rw-r--r-- 1 vagrant vagrant   24 Dec 16 10:35 robots.txt
lrwxr-xr-x 1 vagrant vagrant   63 Mar  2 09:45 storage -> /Users/{{ユーザー名/laravel/アプリディレクトリ名}}/storage/app/public
-rw-r--r-- 1 vagrant vagrant 1194 Dec 16 10:35 web.config
```
`ls -la`で叩くと、下から二番目の行が赤く表示されていると思う。（この記事では赤くありません。）こんなファイルパスは無いと言われているようです。

現在のパスを確認します。
```terminal
$pwd
/home/vagrant/アプリディレクトリ/public
```
ホストOSのディレクトリ構成と全然違うのがわかります。これでやるべき事がわかったので、Homesteadでもシンボリックリンクをしていきます。
Linuxでは`ln -s`でシンボリックリンクできるみたいです。

```terminal
$ln -s /home/vagrant/アプリディレクトリ/public storage
$ls -la
total 20
drwxr-xr-x 1 vagrant vagrant  416 Mar  3  2020 .
drwxr-xr-x 1 vagrant vagrant 1120 Mar  1 11:21 ..
drwxr-xr-x 1 vagrant vagrant  128 Mar  1 11:21 css
-rw-r--r-- 1 vagrant vagrant    0 Dec 16 10:35 favicon.ico
drwxr-xr-x 1 vagrant vagrant   96 Feb  6 12:45 fonts
-rw-r--r-- 1 vagrant vagrant  593 Dec 16 10:35 .htaccess
-rw-r--r-- 1 vagrant vagrant 1823 Feb 17 12:18 index.php
drwxr-xr-x 1 vagrant vagrant   96 Feb  6 12:45 js
-rw-r--r-- 1 vagrant vagrant   71 Feb 25 12:35 mix-manifest.json
drwxr-xr-x 1 vagrant vagrant   64 Feb 16 02:50 post_img
-rw-r--r-- 1 vagrant vagrant   24 Dec 16 10:35 robots.txt
lrwxr-xr-x 1 vagrant vagrant   31 Mar  2 12:06 storage -> /home/vagrant/アプリディレクトリ/storage/app/
-rw-r--r-- 1 vagrant vagrant 1194 Dec 16 10:35 web.config
```
というように変更されていれば完了です。
再度`img`タグのファイルパスを変更していきましょう。

###画像表示

```blade.php
<img src="{{ asset('/storage/'.$post->image) }}">
```
表示できました。

##最後に
今回はHomesteadでシンボリックリンクをしましたが、これがデプロイ時にも必要になってくるのかなと思っています。それで備忘録を残そうと決めました。以上です。