- 投稿日:2020-05-14T23:42:24+09:00
LaravelのPHPUnitでWithFakerなどのTraitが動かない
当初以下のようなコードを書いていたのだが、
namespace Tests\Unit\Repositories; use PHPUnit\Framework\TestCase; use App\Models\User; use App\Constants; use App\Repositories\PgSql\UserRepository; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; class UserRepositoryTest extends TestCase { use WithFaker, RefreshDatabase; protected function setUp(): void { parent::setUp(); } // expected 1 user is found, not others. public function testFindUserByAuthInfo() { $repo = new UserRepository(); // findable $user = factory(User::class)->create([ 'id' => $this->faker->uuid, 'password' => password_hash($this->faker->password(), PASSWORD_BCRYPT), 'account_id' => 1, 'email' => $this->faker->email, ]);実行すると
1) Tests\Unit\Repositories\UserRepositoryTest::testFindUserByAuthInfo
Trying to get property 'uuid' of non-object
と$this->fakerでFakerがインスタンス化できていない模様散々調べた挙げ句、結局
use PHPUnit\Framework\TestCase;
を
use Tests\TestCase;
にしたら直ったというお話。
- 投稿日:2020-05-14T18:53:22+09:00
laravelのルートモデルバインディング
- 投稿日:2020-05-14T14:51:54+09:00
【Laravel】Composer requireでエラー(Installation failed, reverting ./composer.json to its original content.)が出るけどrequireしたい!
composer requireしてみる
今回私はlarevel uiをインストールしたかった。
composer require laravel/uiエラーで乙。
原因
今入れようとしたパッケージとすでに入っているパッケージがそれぞれ同じパッケージの違うバージョンに依存してしまっているよう?
解決法
このようにバージョン指定にアスタリスクをつけて、依存関係が解決されるバージョンが存在するのを祈る。
composer require laravel/ui:0.*
0から試していく。
違うバージョンの時は上の画像のようなエラーが出るが、順次数字を足しながら試していくと合うバージョンが見つかり、インストールできる。
成功っ!!
私の時は、composer require laravel/ui:1.*これで成功しました?
- 投稿日:2020-05-14T11:00:13+09:00
LaravelとVueでSPAを作るときにTypescriptとpugを使う設定をする
Laravel、Vue.js、Typescript、pugでSPAを作ったときのメモ。
docker --version Docker version 19.03.8, build afacb8b扱ったDockerのバージョンは19.03.8。
Fig.1project ├── db ├── web ├── Dockerfile ├── docker-compose.yml └── .env以下の手順で
Fig.1
のような構成のレポジトリを作り、web
ディレクトリの中にLaravelをインストールする。レポジトリと各ファイルを作成
mkdir project_name && cd $_ && touch {docker-compose.yml,Dockerfile,.env}プロジェクトのディレクトリを作成し(
mkdir project_name
)、作成したディレクトリに移動し(cd $_
) 1 、docker-compose.yml
,Dockerfile
,.env
ファイルを作成する(touch {docker-compose.yml,Dockerfile,.env}
)。この時点で
Fig.2
の構成になる。Fig.2project_name ├── Dockerfile ├── docker-compose.yml └── .env各ファイルは以下の内容で書く。
docker-compose.yml
docker-compose.ymlversion: '3' services: web: build: . container_name: ${PROJECT}-web ports: - 80:80 - 3000:3000 volumes: - ./web:/var/www/html/${PROJECT} depends_on: - db db: image: mysql:8 container_name: ${PROJECT}-mysql restart: always environment: MYSQL_DATABASE: ${PROJECT} MYSQL_USER: ${DB_USER} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} TZ: ${TZ} ports: - 3306:3306 volumes: - ./db:/var/lib/mysqlDockerfile
DockerfileFROM php:7.4-fpm COPY --from=node:12 COPY --from=composer:latest /usr/bin/composer /usr/bin/composer RUN apt-get update \ && apt-get install -y wget git zip unzip vim libpq-dev \ && : 'Install PHP Extensions' \ && docker-php-ext-install pdo_mysql pdo_pgsql \ WORKDIR /var/www/html/project_nameマルチステージビルド2で Node.js と Composer の Docker公式イメージ を利用する。
.env
.envPROJECT=project_name DB_USER=user_name DB_PASSWORD=password TZ=Asia/Tokyoコンテナを起動
docker-compose up -dこの時点で
Fig.1
の構成になる。コンテナに入る
docker-compose exec web bashコンテナの中では
composer
やnpm
が使える。# composer --version Composer version 1.10.6 2020-05-06 10:28:10 # node --version v12.16.3 # npm --version 6.14.5Laravelをインストール
# composer create-project --prefer-dist laravel/laravel . // バージョンを指定する場合 (e.g. Laravel6 を指定する場合) # composer create-project --prefer-dist laravel/laravel . "6.*"Laravelの設定
web/config/app.php
app.php<?php return [ // 他の設定 'timezone' => 'Asia/Tokyo', 'locale' => 'ja', // 他の設定 ];設定値を変更。
web/.env
.env// 他の設定 DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=project_name DB_USERNAME=user_name DB_PASSWORD=password // 他の設定データベースに接続するための情報を入れる。
MySQLに接続する場合はDB_CONNECTION=mysql
。
DB_HOST
はdocker-compose.yml
のservices
で設定したdb
とする。
他の設定も.env
で設定したものと同じ。パッケージをインストール
# npm i # npm i vue vue-router pug pug-plain-loader --save-dev # npm i -g typescript # tsc --inittypescriptをグローバルにインストールすると
tsc
コマンドが使えるようになり、# tsc --version Version 3.8.3
tsc --init
とするとtsconfig.json
が生成される。3
tsc --init
をgit init
と混同してtsc init
としないように注意。4ファイルを編集
web/webpack.mix.js
webpack.mix.jsconst mix = require('laravel-mix') /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel application. By default, we are compiling the Sass | file for the application as well as bundling up all the JS files. | */ mix .webpackConfig({ module: { rules: [{ test: /\.pug$/, oneOf: [ { resourceQuery: /^\?vue/, use: ['pug-plain-loader'] }, { use: ['raw-loader', 'pug-plain-loader'] } ] }] } }) .browserSync({ proxy: '0.0.0.0:80', open: false, files: [ 'resources/**/*', 'public/**/*' ] }) .ts('resources/ts/app.ts', 'public/js/app.js') .sass('resources/sass/app.scss', 'public/css') .version()pugを扱うための設定も記載する。5
BrowserSyncの設定を記入。6 7
mix.js()
と書かれていた部分をmix.ts()
変えるだけ。8 あとは扱うファイルの変更に従って引数のファイルもjs
からts
に変更する。web/resources/ts/app.ts
app.tsimport Vue from 'vue' import router from './router' import App from './App.vue' new Vue({ el: '#app', router, components: { App }, template: '<App />' })
web/resources/js/app.js
をweb/resources/ts/app.ts
に書き換える。
ここでApp.vue
とrouter.ts
を読み込む。web/resources/ts/App.vue
App.vue<template lang="pug"> div main RouterView </template>ルートコンポーネント。
ここで Vue Router が提供するRouterView
9 を使う。web/resources/ts/router.ts
router.tsimport Vue from 'vue' import VueRouter from 'vue-router' import Foo from './pages/Foo.vue' import Bar from './pages/Bar.vue' Vue.use(VueRouter) const routes: any = [{ path: '/foo', component: Foo }, { path: '/bar', component: Bar } }] const router = new VueRouter({ mode: 'history', routes }) export default routerルーティングの定義の設定。
History モード 10にすることでURLがハッシュなしで設定できる。web/resources/ts/pages/Foo.vue
Foo.vue<template lang="pug"> .foo h1 Foo </template>web/resources/ts/pages/Bar.vue
Bar.vue<template lang="pug"> .bar h1 Bar </template>web/routes/web.php
web.php<?php Route::get('/{any?}', function () { return view('index'); })->where('any', '.+');web/resources/views/index.blade.php
index.blade.php<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>project_name</title> <script src="{{ mix('js/app.js') }}" defer></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css"> </head> <body> <div id="app"></div> </body> </html>web/vue-shim.d.ts
vue-shim.d.tsdeclare module "*.vue" { import Vue from "vue"; export default Vue; }
Typescript: IDE reports TS2307: Cannot find module error for Vue components imports
とエラーが出たので作成する。11サーバーを起動
# php artisan serve --host 0.0.0.0 --port 80ビルド
# npm run watch-pollhttp://localhost:3000 にアクセスしてブラウザで確認する。
参考
- 投稿日:2020-05-14T10:34:07+09:00
Laravel 画像をアップロードして表示する
目的
- アプリケーションに画像をアップロードして別画面で表示する方法をまとめる
環境
- ハードウェア環境
項目 情報 OS macOS Catalina(10.15.3) ハードウェア MacBook Pro (16-inch ,2019) プロセッサ 2.6 GHz 6コアIntel Core i7 メモリ 16 GB 2667 MHz DDR4 グラフィックス AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB
- ソフトウェア環境
項目 情報 備考 PHP バージョン 7.4.3 Homwbrewを用いて導入 Laravel バージョン 7.0.8 commposerを用いて導入 MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いて導入 事前情報
- 下記の方法、またはそれに準ずる方法で認証機能のついたLaravelアプリが存在すること。
- 既存のマイグレーションファイルがマイグレートされていること。
- ログインユーザ毎に別々の画像のアップロードと表示をすることができる様に実装する。(他のログインユーザがアップロードした画像は表示されない)
概要
- テーブルの作成
- ルーティングの記載
- コントローラの記載
- ビューの記載
- 確認
詳細
テーブルの作成
アプリ名ディレクトリで下記コマンドを実行してモデルファイルとマイグレーションファイルを同時に作成する。
$ php artisan make:model Image --migration;下記にファイルが作成された事を確認する。
アプリ名ディレクトリ/app/Image.php
アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_images_table.php
アプリ名ディレクトリで下記コマンドを実行してマイグレーションファイルを開く。
$ vi database/migrations/YYYY_MM_DD_XXXXXX_create_images_table.php開いたマイグレーションファイルを下記の様に記載する。
アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_images_table.php<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateImagesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('images', function (Blueprint $table) { $table->id(); //下記を追記する $table->foreignId('user_id'); $table->string('file_name'); //上記までを追記する $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('images'); } }アプリ名ディレクトリで下記コマンドを実行してマイグレーションを行う。
$ php artisan migrateルーティングの記載
アプリ名ディレクトリで下記コマンドを実行してルーティングファイルを開く。
$ vi routes/web.php開いたルーティングファイルを下記の様に修正する。
アプリ名ディレクトリ/routes/web.php<?php use Illuminate\Support\Facades\Route; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); //下記を追記 //画像をアップロードするページ Route::get('/upload', 'ImageController@input'); //画像を保存したり画像名をDBに格納する部分 Route::post('/upload', 'ImageController@upload'); //保存した画像を表示するページ Route::get('/output', 'ImageController@output'); //上記までを追記コントローラの記載
アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを作成する。
$ php artisan make:controller ImageController下記のコントローラファイルが作成される。
アプリ名ディレクトリ/app/Http/Controllers/ImageCotroller.php
アプリ名ディレクトリで下記コマンドを実行してコントローラファイルを開く。
vi app/Http/Controllers/ImageCotroller.php
開いたコントローラファイルを下記の様に修正する。
アプリ名ディレクトリ/app/Http/Controllers/ImageCotroller.php<?php namespace App\Http\Controllers; //下記を追加する use Illuminate\Support\Facades\Auth; use Illuminate\Http\Request; //下記を追加する use App\Image; class ImageController extends Controller { //下記を追加する public function input() { return view('image.input'); } public function upload(Request $request) { $this->validate($request, [ 'file' => [ // 必須 'required', // アップロードされたファイルであること 'file', // 画像ファイルであること 'image', // MIMEタイプを指定 'mimes:jpeg,png', ] ]); if ($request->file('file')->isValid([])) { $path = $request->file->store('public'); $file_name = basename($path); $user_id = Auth::id(); $new_image_data = new Image(); $new_image_data->user_id = $user_id; $new_image_data->file_name = $file_name; $new_image_data->save(); return redirect('/output'); } else { return redirect() ->back() ->withInput() ->withErrors(); } } public function output() { $user_id = Auth::id(); $user_images = Image::whereUser_id($user_id)->get(); return view('image.output', ['user_images' => $user_images]); } //上記までを追記 }ビューの記載
アプリ名ディレクトリで下記コマンドを実行してビューファイルを格納するディレクトリを作成する。
$ mkdir resources/views/imageアプリ名ディレクトリで下記コマンドを実行してビューファイルを作成する。
$ touch resources/views/image/input.blade.php $ touch resources/views/image/output.blade.phpアプリ名ディレクトリで下記コマンドを実行して画像をアップロードするビューファイルを開く。
$ vi resources/views/image/input.blade.php開いたビューファイルを下記の様に記載する。
アプリ名ディレクトリ/resources/views/image/input.blade.php@extends('layouts.app') @section('content') <!-- エラーメッセージ。なければ表示しない --> @if ($errors->any()) <ul> @foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> @endif <!-- フォーム --> <form action="/upload" method="POST" enctype="multipart/form-data"> @csrf <label for="photo">画像ファイル:</label> <input type="file" class="form-control" name="file"> <br> <input type="submit"> </form> @endsectionアプリ名ディレクトリで下記コマンドを実行して画像をアップロードするビューファイルを開く。
$ vi resources/views/image/output.blade.php開いたビューファイルを下記の様に記載する。
アプリ名ディレクトリ/resources/views/image/output.blade.php@extends('layouts.app') @section('content') <a href="/upload">画像のアップロードに戻る</a> <br> @foreach ($user_images as $user_image) <img src="{{ asset('storage/' . $user_image['file_name']) }}"> <br> @endforeach @endsection確認
アプリ名ディレクトリで下記コマンドを実行してローカルサーバを起動する。
$ php artisan serve下記にアクセスする。
画面右上の 「LOGIN」もしくは「REGISTER」からログインもしくは新規登録を行う。
下記にアクセスする。
ブラウザ上で下記の様に表示される事を確認する。
「ファイルを選択」をクリックして任意の画像ファイルを開き、「送信」をクリックする。
下記の様に送信した画像が表示される事を確認する。
同アプリで現在ログインしているユーザとは別にユーザを作成しログインを行い、先とは違う画像をアップロードして先の画像とは別の画像表示される事を確認する。
- 投稿日:2020-05-14T02:09:44+09:00
Laravel areaやregionは予約語になっている?
POSTでデータを送る時に
nameにareaやregionを含んだものにすると
無視されることがあるのだが、なんでだろう。要調査や。