質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

2436閲覧

お店画像のアップロードがうまくいきません。

Yachin

総合スコア21

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/08/28 22:50

前提・実現したいこと

度々の投稿失礼します。簡単なラーメン屋投稿アプリを作っているのですが、お店画像のアップロードがうまくいきません。index.blade.phpにbootostrapのcardsを使用して各店の画像を表示していく箇所で詰まっています。コンソールでは画像がnot foundとなっています。解決方法を教えてくださると大変光栄でございます。

発生している問題・エラーメッセージ

各店の画像が表示されない

該当のソースコード

/Applications/MAMP/htdocs/ramenmap/resources/views/index.blade.php

@extends('layout') @section('content') @auth <div class="text-right"> <a href={{ route('shop.new') }} class='btn btn-outline-info'>お店投稿</a> </div> @endauth <h1>お店一覧</h1> @foreach ($shops as $shop) <div class="card mb-3" style="max-width: 540px;"> <div class="row no-gutters"> <div class="col-md-4"> {{-- @foreach($image as $i) @if($i!=null) <img src="/images/{{$i->image}}" class="card-img"> @endif @endforeach --}} {{-- {{ dd($shop->image) }} --}} <img src="{{ $shop->image }}" class="card-img"> </div> <div class="col-md-8"> <div class="card-body"> <h5 class="card-title"> <a href={{ route('shop.detail', ['id' => $shop->id]) }}>{{ $shop->name }}</a> </h5> <p class="card-text">{{ $shop->category->name }} @if ($shop->category->name != $shop->subcategory->name) / {{ $shop->subcategory->name }} @endif <p class="card-text">{{ $shop->address }}</p> <p class="card-text">{{ $shop->user->name }}</p> <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p> </div> </div> </div> </div> @endforeach @endsection

/Applications/MAMP/htdocs/ramenmap/app/Http/Controllers/ShopController.php

<?php namespace App\Http\Controllers; use App\Shop; use App\Category; use App\SubCategory; use App\Pic; use Illuminate\Http\Request; use Intervention\Image\ImageManagerStatic as Image; class ShopController extends Controller { public function __construct() { $this->middleware('auth')->except(['index', 'show']); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $shops = Shop::latest()->get(); $image = Pic::all(); return view('index', ['shops'=>$shops, 'image'=>$image]); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create(Request $request) { $shop = new Shop(); $shop->name = $request->name; $categories = Category::all()->pluck('name', 'id'); $subcategories = SubCategory::all()->pluck('name', 'id'); $image = Pic::all(); return view('new', ['categories' => $categories, 'subcategories' => $subcategories, 'image' => $image]); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $shop = new Shop; $user = \Auth::user(); $shop->name = request('name'); $shop->address= request('address'); $shop->category_id = request('category_id'); $shop->subcategory_id = request('subcategory_id'); $shop->user_id = $user->id; $shop->image = request('image'); $shop->save(); // dd($shop); // $request->validate([ // 'image'=>'required|image|mimes:jpg,jpeg,png|max:2000' // ]); $file = $request->file('image'); // dd($file); $fileName = str_random(20).'.'.$file->getClientOriginalExtension(); // dd($fileName); Image::make($file)->save(public_path('images/'.$fileName)); $pic=new Pic; $pic->image = $fileName; $pic->save(); return redirect()->route('shop.detail', ['id' => $shop->id]); } /** * Display the specified resource. * * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function show($id) { $shop = Shop::find($id); $user = \Auth::user(); if ($user) { $login_user_id = $user->id; } else { $login_user_id = ''; } return view('show', ['shop' => $shop, 'login_user_id'=>$login_user_id]); } /** * Show the form for editing the specified resource. * * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function edit(Shop $shop, $id) { $shop = Shop::find($id); $categories = Category::all()->pluck('name', 'id'); $subcategories = SubCategory::all()->pluck('name', 'id'); return view('edit', ['shop' => $shop, 'categories' => $categories, 'subcategories' => $subcategories]); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function update(Request $request, Shop $shop, $id) { $shop = Shop::find($id); $shop->name = request('name'); $shop->address = request('address'); $shop->category_id = request('category_id'); $shop->subcategory_id = request('subcategory_id'); $shop->save(); return redirect()->route('shop.detail', ['id' => $shop->id]); } /** * Remove the specified resource from storage. * * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function destroy($id) { $shop = Shop::find($id); $shop->destroy($id); return redirect('/shops'); } }

/Applications/MAMP/htdocs/ramenmap/routes/web.php

<?php Route::get('/shops', 'ShopController@index')->name('shop.list'); Route::get('/shop/new', 'ShopController@create')->name('shop.new'); Route::post('/shop', 'ShopController@store')->name('shop.store'); Route::get('/shop/edit/{id}', 'ShopController@edit')->name('shop.edit'); Route::post('/shop/update/{id}', 'ShopController@update')->name('shop.update'); Route::get('/shop/{id}', 'ShopController@show')->name('shop.detail'); Route::delete('/shop/{id}', 'ShopController@destroy')->name('shop.destroy'); Route::get('/', function() { return redirect('/shops'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home');

/Applications/MAMP/htdocs/ramenmap/app/Shop.php

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Shop extends Model { protected $fillable = [ 'name', 'address', 'category_id', 'subcategory_id', 'user_id', 'imgage', ]; public function category() { return $this->belongsTo('App\Category'); } public function subcategory() { return $this->belongsTo('App\SubCategory'); } public function user() { return $this->belongsTo('App\User'); } public function pic() { return $this->belongsTo('App\Pic'); } }

/Applications/MAMP/htdocs/ramenmap/app/Pic.php

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Pic extends Model { // }

試したこと

ググりながら色々とコードを書き直しましたがうまくいかずです。
パスの仕組みが漠然としています。

補足情報(FW/ツールのバージョンなど)

PHP 7.1.23
Laravel Framework 5.7.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/08/28 22:57

登録されていないだけでは?
m.ts10806

2019/08/29 00:15

アップロードの話ではないのでは? アップロードの話であればアップロード処理に指定した場所に画像があるか確認すれば良いだけですし、 今回はあくまで「表示」の問題に見えます。どちらでしょうか?
FKM

2019/08/29 00:18

var_dump($shops)としてみて、必要な情報がきちんと取得できているか確認してみてください
guest

回答3

0

自己解決

はじめはshopstableにイメージファイルのパス、picstableにイメージの詳細を貼り付け、関連づけようとしていました。
しかしながら、自身の漠然とした方法と知見の不足から、ご丁寧な回答をいただいても解決できるところまでには及びませんでした。
最終的にはpicstableを使用するのをやめて、'php artisan storage:link'とコマンド入力し、コードを整理すると解決することができました。
以下、コードを記載します。


/Applications/MAMP/htdocs/ramenmap/resources/views/index.blade.php

@extends('layout') @section('content') @auth <div class="text-right"> <a href={{ route('shop.new') }} class='btn btn-outline-info'>お店投稿</a> </div> @endauth <h1>お店一覧</h1> @foreach ($shops as $shop) <div class="card mb-3" style="max-width: 540px;"> <div class="row no-gutters"> <div class="col-md-4"> <img src="{{ asset('storage/image/'.$shop->image) }}" class="card-img"> </div> <div class="col-md-8"> <div class="card-body"> <h5 class="card-title"> <a href={{ route('shop.detail', ['id' => $shop->id]) }}>{{ $shop->name }}</a> </h5> <p class="card-text">{{ $shop->category->name }} @if ($shop->category->name != $shop->subcategory->name) / {{ $shop->subcategory->name }} @endif <p class="card-text">{{ $shop->address }}</p> <p class="card-text">{{ $shop->user->name }}</p> <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p> </div> </div> </div> </div> @endforeach @endsection

/Applications/MAMP/htdocs/ramenmap/app/Shop.php

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Shop extends Model { protected $fillable = [ 'name', 'address', 'category_id', 'subcategory_id', 'user_id', 'image', ]; public function category() { return $this->belongsTo('App\Category'); } public function subcategory() { return $this->belongsTo('App\SubCategory'); } public function user() { return $this->belongsTo('App\User'); } }

/Applications/MAMP/htdocs/ramenmap/app/Http/Controllers/ShopController.php

<?php namespace App\Http\Controllers; use App\Shop; use App\Category; use App\SubCategory; use Illuminate\Http\Request; class ShopController extends Controller { public function __construct() { $this->middleware('auth')->except(['index', 'show']); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $shops = Shop::latest()->get(); $image = Shop::all(); return view('index', ['shops'=>$shops, 'image'=>$image]); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create(Request $request) { $shop = new Shop(); $shop->name = $request->name; $categories = Category::all()->pluck('name', 'id'); $subcategories = SubCategory::all()->pluck('name', 'id'); return view('new', ['categories' => $categories, 'subcategories' => $subcategories, ]); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $shop = new Shop; $user = \Auth::user(); $shop->name = request('name'); $shop->address= request('address'); $shop->category_id = request('category_id'); $shop->subcategory_id = request('subcategory_id'); $shop->user_id = $user->id; $filename = $request->file('image')->store('public/image'); $shop->image = basename($filename); $shop->save(); return redirect()->route('shop.detail', ['id' => $shop->id]); } /** * Display the specified resource. * * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function show($id) { $shop = Shop::find($id); $user = \Auth::user(); if ($user) { $login_user_id = $user->id; } else { $login_user_id = ''; } return view('show', ['shop' => $shop, 'login_user_id'=>$login_user_id]); } /** * Show the form for editing the specified resource. * * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function edit(Shop $shop, $id) { $shop = Shop::find($id); $categories = Category::all()->pluck('name', 'id'); $subcategories = SubCategory::all()->pluck('name', 'id'); return view('edit', ['shop' => $shop, 'categories' => $categories, 'subcategories' => $subcategories]); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function update(Request $request, Shop $shop, $id) { $shop = Shop::find($id); $shop->name = request('name'); $shop->address = request('address'); $shop->category_id = request('category_id'); $shop->subcategory_id = request('subcategory_id'); $filename = $request->file('image')->store('public/image'); $shop->image = basename($filename); $shop->save(); return redirect()->route('shop.detail', ['id' => $shop->id]); } /** * Remove the specified resource from storage. * * @param \App\Shop $shop * @return \Illuminate\Http\Response */ public function destroy($id) { $shop = Shop::find($id); $shop->destroy($id); return redirect('/shops'); } }

投稿2019/08/30 01:28

編集2019/08/30 02:40
Yachin

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

お店の画像カラムに入っているのは、

php

1 2$shop->image = request('image'); 3

なので、アップロードしたファイルのインスタンスか何かが入っているのかなと思います。
(やったことないので、それがDBにどうなって保存されるのかは分かりませんが・・)

一方、実際にアップロードしたファイルの保存処理では

php

1 2$file = $request->file('image'); 3$fileName = str_random(20).'.'.$file->getClientOriginalExtension(); 4Image::make($file)->save(public_path('images/'.$fileName));

「ファイル名」はランダムな20文字の文字列に、元ファイルの拡張子を付けたものです。

なので、一覧で表示する画像のパスを、/images/{{$shop->image}}としても、アップロード処理で付けた「ランダムなファイル名」と一致することはまずありませんので、not foundになります。

さて。もう一度、画像アップロードのところに戻りますね。

画像アップロードの処理が終わったあと、「ランダムな画像ファイル名」を保存している処理がありますが

php

1$pic=new Pic; 2$pic->image = $fileName; 3$pic->save();

これだけではpicsとshopsが紐づいていませんので、「どこのお店の画像か」が分からないです。

Shopモデルを見ると、

php

1public function pic() 2 { 3 return $this->belongsTo('App\Pic'); 4 }

と書かれていますので、shopsテーブルには、pic_idなるカラムが必要であり、
そこに先ほど保存した$pic->idを入れるべきかなと思います。

ここまで出来たら、お店の一覧に戻りまして。。

お店のデータはShop::with('pic')でお店が持っている画像情報(picsテーブル)まで一緒に取得し、画像のパスには、

php

1<img src="/images/{{ $shop->pic->image }}" class="card-img">

とすれば、一覧に画像が表示されるようになるのではないかなと。


画像のアップロード処理もですが、
モデルのリレーションあたりももう少し理解を深めた方が良さそうかなという印象です。

ご参考までに。。。

投稿2019/08/29 02:09

mix-peach

総合スコア1910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yachin

2019/08/30 01:17

どうもありがとうございました。 本当にご丁寧に教えてくださりましたが、Picモデルを作ってリレーションを張る方法は自身の知見不足のため、なかなかうまくいきませんでした。 結局はコードを見直し、strage:linkの方法で解決しましたが、他ユーザーの為にベストアンサーにさせていただきました。
mix-peach

2019/08/30 02:14

どんな方法でも解決したのであれば、何よりです^^ せっかくベストに選んで頂きましたが、この回答で本当に解決するかを、誰も検証していない・・・ということになるので、他の方も仰るよう「自己解決」の方が良いかも?です。(ベストを外すも残すも、ご判断はお任せいたします!)
Yachin

2019/08/30 02:41

おっしゃる通り、他のユーザーさんがわかりやすいように恐縮ですがベストは自分の回答にさせていただきます。 ありがとうございます。
guest

0

若干あてずっぽうな回答になりますが、saveで
Image::make($file)->save(public_path('images/'.$fileName));

としているのでしたら、表示時もpublic_path()を使って参照させる必要があるのではないでしょうか。

あくまで「正しくその場所に画像が保存されている前提」なので、まずは画像がちゃんと保存されているかディレクトリ内を確認してから表示時のパスを調整してください。

投稿2019/08/29 01:57

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yachin

2019/08/30 01:18

いつもありがとうございます。今回は一からコードを見直し、自己解決させていただきました。
m.ts10806

2019/08/30 01:27

ついた回答と違う解決方法であれば、それはそれで別途具体的に回答として残しておいたほうが他のユーザーのためになると思います。
m.ts10806

2019/08/30 01:27

あとそれで自己解決なのでしたら自身で書いた回答をベストアンサーとすべきですね。
Yachin

2019/08/30 02:44

おっしゃる通り他のユーザーさんがわかりやすいように、自身のコードとベストアンサーを編集させていただきました。ありがとうございます。
m.ts10806

2019/08/30 02:45

実際の解決策とのことで上げておきました(+1)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問