- 投稿日:2019-08-28T23:25:50+09:00
Laravel5.8 MAMPを利用した開発環境構築
内容
- MacでのMAMPを使用したLaravel5.8開発環境を構築
- 環境構築と言っても必要なものをインストールし、プロジェクトを作成するだけのシンプルな手順解説
環境
- OS macOS Mojave 10.14.6
- MAMP 5.3
- PHP 7.3.1
- MySQL 5.7.25
- Composer 1.8.6
MAMPの導入
入っていることを想定して省略
Composerのインストール
LaravelなどのPHPのフレームワークを使用する際にComposerというPHPのパッケージ管理ソフトを利用する。
# Composerのインストール $ curl -sS https://getcomposer.org/installer | php # ファイルをusr/local/binへ移動 $ sudo mv composer.phar /usr/local/bin/composer # パーミッションの変更 # aは全てという意味、xは実行権、この場合全ての項目で実行権を与えるということ $ chmod a+x /usr/local/bin/composerこれでComposerがインストールされ、Laravelをインストールする準備完了
# 確認 $ composer -VLaravelのインストール
Composerを使ってLaravelをインストールする
$ composer global require "laravel/installer"Laravelインストール後は環境変数PATHを設定する
$ export PATH="$PATH:~/.composer/vendor/bin" # パスをsourceコマンドで有効にする $ source ~/.bash_profile※ PATHの通し方についての説明
https://qiita.com/KZ-taran/items/0cb2cfa64625ec1b58a9プロジェクトの作成
/Application/MAMP/htdocs/にlaravel_sampleというプロジェクトを作成することとする
/Application/MAMP/htdocs/に移動し、下記コマンド入力/Application/MAMP/htdocs/# /Application/MAMP/htdocs/に移動 $ cd /Application/MAMP/htdocs/ # Laravelコマンドを使ってプロジェクトの作成 $ laravel new {プロジェクト名} # laravel_sampleというプロジェクトを作成する場合 $ laravel new laravel_sampleコマンド実行後、成功すればプロジェクトが生成される。
laravelのフレームワークのversionを確認する場合/Application/MAMP/htdocs/laravel_sample/# プロジェクトまで移動 $ cd /Application/MAMP/htdocs/laravel_sample/ # Laravelフレームワークのバージョン確認 php artisan --version # (補足)単にLaravelインストーラーのバージョン確認 $ laravel -VMySQLを使用する場合
MySQLへのログイン(PATHを通していない場合)
# PATHを通さないmysqlログイン手順 # MAMPのmysqlmコマンドが入っているディレクトリに移動する $ cd /Applications/MAMP/Library/bin/ # DBへログイン $ ./mysql -u root -pMySQLへのログイン(PATHを通す場合)
# エディタviで~/.bash_profileを編集する $ vim ~/.bash_profile # 下記内容を追加 # テキスト挿入の際にはiを押してから $ export PATH=/Applications/MAMP/Library/bin:$PATH # 書き込み終了の際はescで抜けてから:wqで保存し、次のコードで変更を反映させる $ source ~/.bash_profileこれにより、どのディレクトリからでも次のコマンドでmysqlログイン可能になる
$ mysql -u root -pプロジェクトのenvファイルの修正
DB設定値を使用するMySQLの情報へ変更していく
/Application/MAMP/htdocs/laravel_sample/.env// 変更前 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD= // 変更後 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_sample // (使用するDB名) DB_USERNAME=root // (DBのユーザー名(仮にrootとする)) DB_PASSWORD=root // (DBのPW(仮にrootとする))DBのコネクションの設定
/config/databases.phpの変更/Application/MAMP/htdocs/laravel_sample/config/databases.php// 変更箇所 デフォルト 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), // 今回の修正 'database' => env('DB_DATABASE', 'laravel_sample(.envで設定したDB名)'), 'username' => env('DB_USERNAME', 'root(.envで設定したユーザー名)'), 'password' => env('DB_PASSWORD', 'root(.envで設定したPASS)'), 'unix_socket' => env('DB_SOCKET', '/Applications/MAMP/tmp/mysql/mysql.sock'), // 'DB_SOCKET'はmysqlで次のコマンドで確認できる SHOW VARIABLES LIKE '%sock%';デバッグ設定の有効
Laravelではエラーや例外処理はすでに設定されているためtry, catchを書く必要はなく、アプリケーションエラー発生時にどの程度の情報を表示させるか
config/app.php設定ファイルのdebug設定オプションで設定する/Application/MAMP/htdocs/laravel_sample/config/app.php// 変更前 // デバッグを有効にする際には'APP_DEBUG'をtrueにし、リリースするときには必ずfalseにする 'debug' => env('APP_DEBUG', false), // 変更後 'debug' => env('APP_DEBUG', true),サーバーの起動
LaravelにはWebサーバー機能が備わっている
# サーバー起動方法 $ php artisan serve以上で完了
http://localhost:8000で確認できる(補足) Laravel よく使うディレクトリ構成
https://readouble.com/laravel/5.8/ja/structure.html
app // ModelやContoller └─ Http └─ Controllers // Controller config // 各種設定ファイル database // マイグレーションと初期設定(シーディング) ├─ factories ├─ migrations // マイグレーションファイル └─ seeds // シーディングファイル public // アセット(画像, JavaScript, CSSなど) resources // Viewやアセットのビルド前のファイル └─ views // View routes └─ web.php // ルーティング設定 storage // コンパイルされたBladeテンプレート、ファイルベースのセッション、ファイルキャッシュなどのフレーム └─ logs // ログ
- 投稿日:2019-08-28T22:31:04+09:00
Laravel 5.8 任意に設定したカラムを外部キーとする場合のリレーション
変則的なテーブル設計のリレーションを定義する機会があり、調べるのに時間がかかったためメモります。
今回使うテーブルの設計
1つのwork(仕事)に対して複数のapplicaiton(応募)が存在する一対多の関係。これら2つのテーブルをwork_idでリレーションして簡単に呼び出せるようにする。
特筆すべき点
・workテーブルの主キーがidではなくwork_id
・work_idには32桁のuuidが入る。typeはstring環境
OS : macOS Mojave 10.14.5
PHP : 7.3.1
mysql : Ver 14.14 Distrib 5.6.42, for osx10.14 (x86_64) using EditLine wrapper
Laravel : 5.7.6手順
・migration
・Workの主キーの設定
・リレーションの設定をモデルに記述migration
workテーブル
create_works_table.phppublic function up() { Schema::create('works', function (Blueprint $table) { $table->char('work_id',32); $table->primary('work_id'); //work_idを主キーに設定 $table->string('catch_copy',50); $table->string('place',50); $table->string('description',500); $table->timestamps(); }); }applicationテーブル
create_applications_table.phppublic function up() { Schema::create('applications', function (Blueprint $table) { $table->bigIncrements('id'); $table->char('work_id',32); $table->foreign('work_id')->references('work_id')->on('works'); // このテーブルのwork_idを、worksテーブルのwork_idを参照する外部キーにする $table->string('message',500); $table->timestamps(); }); }Workの主キーの設定
workの主キーの名前はidではなく、かつuuidであります。laravel標準のものとは違うため少し設定が必要となります。
Work.phpclass Work extends Model { protected $primaryKey = 'work_id'; // 主キーをオーバーライド public $incrementing = false; // IDが自動増分されない場合 protected $keyType = 'string' // 主キーが整数でない場合 }Laravelの主キーについての設定についてはドキュメントの以下のページに記載されています。
Eloquentの準備(https://readouble.com/laravel/5.8/ja/eloquent.html)$primaryKey
各モデルの親クラスであるModel.phpを確認すると以下のように'id'がデフォルトとなっています。
Model.phpprotected $primaryKey = 'id';$primaryKeyをWork.phpでオーバーライドしてあげることで、Workの主キーをwork_idに設定することができます。
$incrementing
$incrementingは、IDが自動増分されるかどうかのプロパティです。Model.phpではtrueとなっています。
今回はuuidゆえ自動増分されないので、falseにしてあげます。$keyType
$keyTypeは、主キーtypeについてのプロパティです。
Model.phpではintとなっています。整数ではない場合、stringに設定します。(incrementing、keyTypeの設定はなくても動きました。書かないとどんな時に困るのか教えて欲しいです。)
リレーションの設定をモデルに記述
まずは先ほどのWork.phpに書き加えます
Work.phpclass Work extends Model { protected $primaryKey = 'work_id'; public $incrementing = false; protected $keyType = 'string'; public function applications(){ return $this->hasMany('App\Application', 'work_id'); // 第二引数にforeign_keyを設定する。 } }次はApplication.phpです。
Application.phpclass Application extends Model { public function work(){ return $this->belongsTo('App\Work','work_id'); // 第二引数にforeign_keyを設定する。 } }ドキュメントは以下になります。
リレーション(https://readouble.com/laravel/5.8/ja/eloquent-relationships.html)foreign_key
foreign_keyは引数で指定しない場合、モデル名 +_+ $primary_keyという形になります。
先ほど、workの$primary_keyをオーバーライドしたため、'work_work_id'となってしまっています。これではエラーが起きてしまうため、今度はforeign_keyをオーバーライドしてあげましょう。
参考
hasMany,hasOne,belongsToなどのリレーション関連のメソッドは
Illuminate\Database\Eloquent\Concerns\HasRelationships.phpに記述されています。HasRelationships.phppublic function hasOne($related, $foreignKey = null, $localKey = null) { $instance = $this->newRelatedInstance($related); $foreignKey = $foreignKey ?: $this->getForeignKey(); $localKey = $localKey ?: $this->getKeyName(); return $this->newHasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey); }local_key
今回は指定しませんでしたが、foreign_keyだけではなく、local_keyも指定することができます。
local_keyはデフォルトだと、primary_keyになります。今回はもうすでに$primary_keyをwork_idとオーバーライドしたため新たな設定は必要ありませんでした。
もし、Work.phpで$primary_keyをオーバーライドしなかった場合は、local_keyつまり第三引数にwork_idを入れてあげると動きました。
終わりに
ネットでもググってもあんま情報探せなかったけど、ドキュメントを見たら書いてあった。いい経験になった気がする。
変なところあったら優しく教えてください。お願いします。
- 投稿日:2019-08-28T20:17:45+09:00
Vagrant+VirtualBoxで作った仮想環境(CentOS)にLaravel環境構築
はじめに
以前参画していたプロジェクトにて、コンテナ内のLaravelログをCloudWatch Logsに出力したいという要望があった。
参画しておきながら、あまり開発環境構成などの理解が浅く、この機会にLinux環境にLaravel環境を構築する手順を身につける。目次
- Vagrant、VirtualBoxのインストール
- 仮想環境(CentOS)の構築
- PHPのインストール
- composerのインストール
- Laravelのインストール
Vagrant、VirtualBoxのインストール
VirtualBox
\https://www.virtualbox.org/wiki/Downloads仮想環境(CentOS)の構築
コマンドプロンプトを起動し、適当なフォルダへ移動します。
> d: > cd d:\workCentOSのイメージをダウンロードします。(これ、結構かかります)
> vagrant box add centos/7CentOS起動用のVagrantfileの雛形を作成します。
> vagrant init centos/7作成したVagrantfileの雛形をカスタマイズします。
D:\work フォルダに Vagrantfileファイルが出来ているので、テキストエディタで開いて、以下の編集を行います。
以下の行のコメントアウトを解除するだけです。Vagrantfile35| config.vm.network "private_network", ip: "192.168.33.10"
- 35行目の編集は、後ほどCentOS上で起動されたLaravelのビルドインWebサーバーへ接続する為に必要になります。
さあ、Vagrantを起動しましょう。
> vagrant upカレントフォルダのvagrantfileを参照して、そこに記載してある仮想環境を構築、起動します。
仮想環境(CentOS)が起動しているので、仮想環境にSSHで接続しましょう。
> vagrant sshPHPのインストール
最新のLaravel 5.8 では、PHP 7.1.3 以上が必要なので、ここでは PHP 7.2をインストールすることにします。
通常なら、yum install でphpを指定すればよいのですが、既定のリポジトリには PHP7.2系が配布されていない為、リポジトリを追加する必要があります。今回はPHP7.2を配布しているRemiリポジトリを追加しますが、Remiリポジトリを追加する為に、EPELリポジトリを追加する必要があります。
このあたりの手順は、RemiさんのWebサイトの設定ウィザードで対象OSなどを選択して、確認するのが一番かと思います。以下で行う
yum installコマンドには全て-yオプションをつけていますが、これは途中の確認を全てYESで答えるオプションです。では、EPELリポジトリの追加から行っていきます。
$ sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpmRemiリポジトリを追加します。
$ sudo yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpmyum-config-managerコマンド用にyum-utilsをインストールします。
$ sudo yum -y install yum-utilsremiリポジトリの有効化を行います。
$ sudo yum-config-manager --enable remi-php72PHP 7.2 と関連パッケージをインストールします。
$ sudo yum -y install php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt php-zip php-unzipインストールを確認します。
$ rpm -qa | grep php $ php -v PHP 7.2.21 (cli) (built: Jul 30 2019 14:46:08) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies無事 PHP 7.2.21 がインストールできました。
余談(Software Collections(SCL)リポジトリ)
こちらの記事によると、PHP 7.xを配布する公式のリポジトリ Software Collections(SCL) もあるそうですが、これで配布されたPHPを利用するには、ログイン毎、ソフトウェア毎に'scl enable'コマンドでSCLを有効化する必要があり、後々面倒になりそうなので、今回の手順ではRemiリポジトリからインストールしました。
PHPの設定
PHPの設定ファイル、/etc/php.ini をviで編集します。
$ sudo vi /etc/php.ini編集箇所は以下の通りです。
php.inidate.timezone = "Asia/Tokyo" mbstring.language = Japanese mbstring.internal_encoding = UTF-8 mbstring.http_input = UTF-8 mbstring.http_output = pass mbstring.encoding_translation = On mbstring.detect_order = auto mbstring.substitute_character = nonecomposerをインストール
composerは、PHPのライブラリ管理ツールです。
今回はLaravelのインストールに使いますが、このLaravelのインストール時に必要なPHPライブラリを自動でインストールしてくれます。参考:PHP開発でComposerを使わないなんてありえない!基礎編
PHPのインストールほど面倒ではないです。
# curl -sS https://getcomposer.org/installer | phpcurlでダウンロードしてきたインストーラをPHPで実行しています。
ダウンロードとインストールが完了すると、カレントディレクトリに
composer.pharというファイルができます。
これが実行ファイルなので、パスの通ったディレクトリに移動します。$ mv composer.phar /usr/local/bin/composerこれで、
composerコマンドが使えます。
早速バージョン確認してみましょう。$ composer -v ______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 1.9.0 2019-08-02 20:55:32インストール完了です。
Laravelのインストール
composerを使ってインストールします。
$ composer global require "laravel/installer"今回は
/var/www配下にプロジェクトを作成していこうと思います。
Laravelの新規プロジェクトを作成する際のコマンドcomposerは、一般ユーザー権限で実行されますが、/var/wwwディレクトリの書き込み権限が無いので、このディレクトリの所有者変更と書き込み権限付与を行います。$ ls -al /var/www total 0 drwxr-xr-x. 4 root root 33 Aug 28 09:31 . drwxr-xr-x. 19 root root 265 Aug 28 09:31 .. drwxr-xr-x. 2 root root 6 Jul 29 17:19 cgi-bin drwxr-xr-x. 2 root root 6 Jul 29 17:19 html $ cd /var/www $ sudo chown -Rv root:$USER . changed ownership of ‘./cgi-bin’ from root:root to root:vagrant changed ownership of ‘./html’ from root:root to root:vagrant changed ownership of ‘.’ from root:root to root:vagrant $ sudo chmod -Rv g+rw . mode of ‘.’ changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x) mode of ‘./cgi-bin’ changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x) mode of ‘./html’ changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x)では、新しいLaravelプロジェクトを作成します。
$ composer create-project --prefer-dist laravel/laravel blog "5.6.*"※プロジェクトが作成されると、最後にキーが同時に作成されるので、残しておきましょう。
動作確認します。
$ cd blog $ php artisan --version Laravel Framework 5.6.39Laravelのバージョンが表示されればプロジェクトの作成は無事完了です。
あとは、PHPのビルドインWebサーバーを使用して動作確認するだけですが、CentOSにはSELinuxが導入されており、これが動作確認の邪魔になります。
一時的にアクセス制御を無効化して、動作確認をします。(恒久的に無効化する方法もありますが、ここでは割愛します)$ sudo setenforce 0 $ php -S 0.0.0.0:8000 -t public PHP 7.2.21 Development Server started at Wed Aug 28 11:04:35 2019 Listening on http://0.0.0.0:8000 Document root is /var/www/blog/public Press Ctrl-C to quit.この状態で、ホストOSのブラウザで、
http://192.168.33.10:8000にアクセスしてください。
おわりに
次は、Laravelの環境をBuildしてコンテナ化する手順を身につけたい
参考
https://qiita.com/inexp_eng4432/items/ec818f151b8ad516988b
https://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e
https://qiita.com/takeshi_nozawa/items/ee01981b4fc338209437
https://rpms.remirepo.net/wizard/
https://eng-entrance.com/linux-selinux
- 投稿日:2019-08-28T16:55:34+09:00
Laravelで.env が読み込めなくなった
ほんとにメモ程度に。
他の人がenvファイルに更新をしたので
そのまま加筆したら反映されなかったのでqiita.rbphp artisan config:cache php artisan view:clearを実行したところenvファイル自体読み込めなくなり
Undefined index:エラーに、、、結局
bootstrap/cache/config.php
を削除したら正常に読み込めた。
- 投稿日:2019-08-28T02:18:58+09:00
LaravelにおけるN対Nリレーションをやってみた
目的
Laravel上でN対Nリレーションのものを何か実装してみる。
前提
下記の環境で実装した。
- PHP7.1.x
- Laravel5.8.x
- PostgreSQL11.4
上記環境にてN対Nのリレーションを用いたものを実装してみた。
サンプル仕様
本とその著者について考える。
本には著者が必ずいるが一人とは限らない。また著者は本を複数冊出す。
よって本と著者の関係はN対Nになる。
そこで、下記のようなテーブル構造とする。
サンプルのために簡略化のため本はタイトルと内容のみ、著者は名前のみとする。
画面構成は
の2画面とする。
また簡略化のため、authorsテーブルには既に3人の著者を登録済みとする。実装手順
下記の手順で実装した。
- モデル作成
- コントローラー作成
- ビューの作成
モデル作成
まず、books(書籍データ)のモデルを作成する。Laravelなのでartisanで雛形作成する。
% php artisan make:model book --migration以上でBook.phpとbooksのミグレーションファイルが作成される。
同様にauthors(著者データ)のモデルも作成する。% php artisan make:model author --migrationまず、ミグレーションを片付けてしまおう。
****_create_books_table.php<?php 〜 省略 〜 class CreateBooksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('books', function (Blueprint $table) { $table->bigIncrements('id'); // ここから $table->string("title"); $table->text("memo"); $table->timestamps(); // ここまでを追加記述 }); } 〜 省略 〜 }****_create_authors_table.php<?php 〜 省略 〜 class CreateAuthorsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('authors', function (Blueprint $table) { $table->bigIncrements('id'); // ここから $table->string("name"); $table->timestamps(); // ここまでを追加記述 }); } 〜 省略 〜 }また、リンクテーブルを作成する必要があるので、モデルは作成する必要がないため、ミグレーションのみ作成する。
% php artisan make:migration author_book****_create_author_book_table.php<?php 〜 省略 〜 class CreateBookAuthor extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('book_author', function (Blueprint $table) { $table->bigIncrements('id'); // ここから $table->integer("book_id"); $table->integer("author_id"); // ここまでを追加記述 }); } 〜 省略 〜 }ここでまずテーブルを作成してしまう。
% php artisan migrateこれでデータベースの準備は整ったので、モデルのリレーション設定を行う。
まずbookモデルBook.php<?php namespace App; use Illuminate\Database\Eloquent\Model; class Book extends Model { public function authors() { return $this->belongsToMany(Author::class); } }authorsとリンクするので、authors()メソッドを作成して、belongsToMany()を上記のように記述する。
同様にauthorsモデルBook.php<?php namespace App; use Illuminate\Database\Eloquent\Model; class Author extends Model { public function books() { return $this->belongsToMany(Book::class); } }以上で、モデルの作成は終了である。
コントローラ
booksのコントローラーを作成する。
例によってartisanにて雛形を作成する。% php artisan make:controller BookController --resource --model=Book以上でコントローラーの雛形が作成される。
ルーティングは下記のように設定した。routes/web.phpRoute::resource("books","BookController");コントローラーの中身を埋めていこう。
index(書籍一覧)
indexは特に説明することはないが、Bookモデルでリレーションの設定をしているため、
Authorを取得するコードを記述する必要はない。BookController.phppublic function index() { $books = Book::get(); return view("books.index",["books"=>$books]); }create(書籍登録画面)
新規登録画面である。Authorのチェックボックスを作成するため、Authorのリストが必要になる。
BookController.phppublic function create() { $authors = Author::pluck("name","id")->toArray(); return view("books.create",compact('authors')); }store(書籍登録実行)
bookレコード作成とauthorとのリンク(author_book)レコードの作成を行う。
BookController.phppublic function store(Request $request) { // フォーム値からauthor_idの配列を抜き出す。 $authors = $request->input("author_id",[]); unset($request["author_id"]); // bookの登録 $book = new Book(); $book->title = $request->title; $book->memo = $request->memo; $book->save(); // authorとのリレーションレコードを登録 $book->authors()->attach($authors); return redirect( route("books.edit",$book->id)) ->with("flash_message","保存しました"); }$book->authors()->attach($authors);の一行でリンクテーブルのレコードを作成してくれる。
edit(書籍更新画面)
更新画面である。これもAuthorのチェックボックスを作成するため、Authorのリストが必要になる。
BookController.phppublic function edit(Book $book) { $authors = Author::pluck("name","id")->toArray(); return view("books.edit",["book"=>$book,"authors"=>$authors]); }update(書籍更新実行)
bookレコード更新とauthorとのリンク(author_book)レコードの更新を行う。
BookController.phppublic function update(Request $request, Book $book) { // bookの更新 $book->title = $request->title; $book->memo = $request->memo; $book->save(); // authorとのリレーションレコードの更新 $book->authors()->sync($request->input('author_id',[])); return redirect( route("books.edit",$book->id)) ->with("flash_message","保存しました"); }これもリンクテーブルの更新は1行で済む。
$book->authors()->sync($request->input('author_id',[]));delete(書籍削除)
bookレコード削除とauthorとのリンク(author_book)レコードの削除を行う。
BookController.phppublic function destroy(Book $book) { // authorとのリレーションレコードの削除 $book->authors()->detach(); // bookの削除 $book->delete(); return redirect( route("books.index")) ->with("flash_message","削除しました"); }これもリンクテーブルの削除は1行で済む。
$book->authors()->detach();ビューの作成
最後にビューである。
index(書籍一覧)
一覧表示部分のみ抜粋する。
<table class="table table-stripe"> <tr> <th>ID</th> <th>タイトル</th> <th>著者</th> </tr> @foreach($books as $book) <tr> <td>{{ $book->id }}</td> <td>{{ $book->title }}</td> <td>@foreach($book->authors as $author) {{$author->name}} @endforeach</td> <td> <a href="{{ route('books.edit',$book->id) }}" class="btn btn-primary">更新</a> <form action="{{ route('books.destroy',$book->id) }}" id="form_{{ $book->id }}" method="post" style="display:inline"> {{ csrf_field() }} {{ method_field('delete') }} <a href="#" data-id="{{ $book->id }}" onClick="delAdmin(this);" class="btn btn-danger">削除</a> </form> </td> </tr> @endforeach </table> <a href="{{ route('books.create') }}" class="btn btn-primary">追加</a>$book->authorsにリンクされているauthorが入っているため、$author->nameを表示するだけで良い。
create(新規登録)
フォームのみ抜粋する。
<form method="post" action="{{ route('books.store') }}" enctype="multipart/form-data"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label for="title">タイトル</label> <input type="text" class="form-control" name="title" id="title"> </div> <div class="form-group"> <label for="memo">内容</label> <textarea class="form-control" rows="3" name="memo" id="memo"></textarea> </div> <div class="form-group"> <label for="author">著者</label> @foreach( $authors as $key => $author) <label class="checkbox-inline"> <input type="checkbox" name="author_id[]" value="{{ $key }}">{{ $author }} </label> @endforeach </div> <input type="submit" class="btn btn-primary" value="登録"> <a href="{{ route('books.index') }}" class="btn btn-default">一覧へ</a> </form>edit(更新画面)
フォームのみ抜粋する。
<form method="post" action="{{ route('books.update',$book->id) }}" enctype="multipart/form-data"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label for="title">タイトル</label> <input type="text" class="form-control" name="title" id="title" value="{{ old('title',$book->title) }}"> </div> <div class="form-group"> <label for="memo">内容</label> <textarea class="form-control" rows="3" name="memo" id="memo">{{ old('memo',$book->memo) }}</textarea> </div> <div class="form-group"> <label for="author">著者</label> @foreach( $authors as $key => $author) @php $bCheck = false; if ( isset($book->authors) && $book->authors->contains($key)) { $bCheck=true; } @endphp <label class="checkbox-inline"> <input type="checkbox" name="author_id[]" value="{{ $key }}" @if ($bCheck==true) checked @endif>{{ $author }} </label> @endforeach </div> <input type="submit" class="btn btn-primary" value="登録"> <a href="{{ route('books.index') }}" class="btn btn-default">一覧へ</a> </form>下記のコードで、リンクされているかどうか判定する。
@foreach( $authors as $key => $author) @php $bCheck = false; if ( isset($book->authors) && $book->authors->contains($key)) { $bCheck=true; } @endphp考察
以上のようにN対Nのリレーションが相当楽に実装できるのである。
少し気持ちが悪いところはbookとauthorのリンクテーブルは
book_author
としたいところであるが、うまく行かなかった。どうやらアルファベット順でないと
ダメなようである。ソース一式はGithubにアップした。
https://github.com/kingcony/bookauthor_Sample




