20200104のlaravelに関する記事は14件です。

プログラミングをかじったからには何らかの制作物を作りたい#3 ~作り直し編、完成したもの~

説明

このエントリーは初心者がとりあえず何かを作りたいと考え、それのみを理由にして記述しているものの3です。そのため、技術的な誤りや勘違いが多分に含まれている可能性があります。ご了承くださいませ。もしよろしければご指摘やご教示を頂けましたら幸いです。

前回のあらすじ

プログラミングをかじったからには何らかの制作物を作りたい# 2
https://qiita.com/tatsuki1112/items/bf363ff7e0a1678eebd6
じゃんけん自体を書いたり、Bootstrapでページを一応レスポンシブ化した。

作り直しとは

じつはこのじゃんけんサイトは最初PythonのFlaskで作成していた。しかしなんとなくやる気が起きずにだいぶ放置していた。その後、PHP、Laravelを使用している会社でインターンを行うこととなったので、勉強をかねてLaravelで作成しようと思い立ち作り直して再開した。

できたもの

このエントリーを行ったときにはこのじゃんけんサイトもうすでに完成していて、やったことの整理という意味で記述しています。
一応の成果物はこちらにあるので、お暇な際にでも遊んでいただけると幸いです。
https://www.mend0.top

実際に使ったもの

Docker 19.03.5
Docker-compose 1.25.0
PHP 7.3.13
Laravel 6.3.0
nginx 1.17
mysql 8.0
jquery
Bootstrap 4

conoha vps 最安プラン
centos 7.7

こんな感じでしょうか

大いに参考にさせていただいたもの

いきなりDockerやLaravelの環境を構築するのは非常に困難なので、以下を参考に環境を整えました。

Laravelの開発環境をDockerを使って構築する
https://qiita.com/ucan-lab/items/17c806973e69792ada99

Laravel 6.0 基本のタスクリスト
https://qiita.com/ucan-lab/items/36f6e89abad26a68f69a

というかほとんどこちらのタスクリストを改変して作成したようなものです。偉大ですね。

あそびかた

それぞれの制作や公開の過程でどのような手順を踏んだかはともかくとして、とりあえずはどんな物ができたのかを御覧いただきたいと思います。

トップページ

スクリーンショット 2020-01-04 23.21.27.png

強い手を探す

指定した回数じゃんけんを行い、そのなかで最も勝数が多かった手を表示するものです。じゃんけんの手を決める自信がないときに利用してください。
スクリーンショット 2020-01-04 23.26.58.png

たとえば99999回じゃんけんを行わせると...
スクリーンショット 2020-01-04 23.28.17.png

このように試行回数などとともに一番つよいじゃんけんの手を教えてくれます。

勝敗を決める

じゃんけんを行う際に、3回勝負などで決着を付ける場合があります。しかしもはや3回では納得ができない場合に利用してください。
スクリーンショット 2020-01-04 23.34.07.png
例えばこの二者にじゃんけんをおこなわせると...

スクリーンショット 2020-01-04 23.35.43.png
こちらが勝利したようです。

回数を見る

こちらの画面ではいままでに行われたじゃんけんの総回数、最大回数、各手の勝利回数を見ることができます。それだけです。
スクリーンショット 2020-01-04 23.39.34.png

レッツじゃんけん!!!!

実際にどのように作成したか、どういったところに苦労したかなどは次回以降記述します。

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

Laravelでよく使うコマンド、記法

新規プロジェクト作成

$ laravel new (アプリ名)

または

$ composer create-project laravel/laravel (アプリ名) --prefer-dist

artisanコマンド

コントローラの作成

$ php artisan make:controller (コントローラ名)

マイグレーションの作成

$ php artisan make:migration create_(テーブル名)_table

モデルの作成

$ php artisan make:model (モデル名)

シーダーの作成

$ php artisan make:seeder (テーブル名)TableSeeder

マイグレーションとシーダーの反映

$ php artisan migrate --seed

データベースのリフレッシュ

$ php artisan migrate:reset

web.php記法

getメソッド

routes/web.php
Route::get('(相対パス)', function () {
    // 処理
});
routes/web.php
Route::get('(相対パス)', 'コントローラ名@関数')->name('名前');

postメソッド

routes/web.php
Route::post('(相対パス)', 'コントローラ名@関数')->name('名前');

URLに変数を混ぜる

routes/web.php
Route::get('/hoge/{id}', 'コントローラ名@関数')->name('名前');
routes/web.php
Route::get('/hoge/{id?}', 'コントローラ名@関数')->name('名前');

マイグレーション記法

Schema::table('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
});

カラムタイプ

コマンド 説明
$table->bigIncrements('id'); BIGINT
$table->integer('votes'); integer(整数)
$table->string('name', 100); string(文字列)
$table->float('amount', 8, 2); float(実数)
$table->boolean('confirmed'); boolean(真偽)
$table->date('created_at'); date(日付)
$table->timestamp('added_on'); timestamp(時間)

カラム修飾子

コマンド 説明
->unique() uniqueキー追加
->nullable() NULL値を許容

モデル記法

fillable

create()やupdate()を受け付けるホワイトリスト

protected $fillable = [
    'name', 'email', 'password'
];

guarded

create()やupdate()を受け付けないブラックリスト

protected $guarded = [
     'create_at', 'update_at'
];

hidden

パスワードなどの秘匿性の高いカラム

protected $hidden = [
     'password', 'remember_token'
];

シーダー記法

database/seeds/DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        Model::unguard();

        $this->call('Seeder名');

        Model::reguard();
    }
}
<?php

use Illuminate\Database\Seeder;

use App\モデル名;

class MemoTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('テーブル名')->delete(); //最初に全件削除

        モデル名::create([
            'name' => 'aaa', 'email' => 'aaa@example.com'
        ]);
    }
}

データの取得

全件取得

$items = Item::get();

最初の要素だけ取得

$item = Item::first();

id指定で取得

idというカラムがある場合のみ使用可能

$id = 1;
$item = Item::find($id); // 配列ではなく要素
$items = Item::find([1, 3]); // 長さ2の配列

条件付きでデータを取得

nameというカラムの値が「名前1」というデータを全件取得する。

$items = Item::where('name', '名前1')->get();

AND/OR検索

AND検索

15歳の鈴木さんのデータのみ取得する。

$items = Item::where('age', 15)
    ->where('name', '鈴木')
    ->get();
$items = Item::where([
    ['age', 15],
    ['name', '鈴木']
])->get();
OR検索

鈴木さんと山田さんのデータを取得する。

$items = Item::where('name', '鈴木')
    ->orWhere('name', '山田')
    ->get();

特定の文字列を含んだデータの取得

nameに「川」という文字列を含むデータを全件取得する。

$items = Item::where('name', 'like', '%川%')->get();

比較によるデータの取得

idが5よりも大きいデータを全件取得する。

$items = Item::where('id', '>', 5)->get();

idが5以下のデータを全件取得する。

$items = Item::where('id', '<=', 5)->get();

時間情報で検索

日付で検索
$items = Item::whereDate('created_at', '2020-01-04')->get();
年で検索
$items = Item::whereYear('created_at', '2020')->get();
月で検索
$items = Item::whereDate('created_at', '1')->get();
日で検索
$items = Item::whereDay('created_at', '4')->get();

並び替えて取得

昇順 (1, 2, 3, 4)
$items = Item::orderBy('id', 'asc')->get();
降順 (4, 3, 2, 1)
$items = Item::orderBy('id', 'desc')->get();

集約したデータの取得

件数の取得
$count = Item::count();
最大値の取得

idが一番大きいデータを取得

$item = Item::max('id');

データの編集や削除

データの更新

nameを鈴木に変更する

$item = Item::first();
$item->update([
    'name' => '鈴木'
]);

データの追加

25歳の鈴木さんのデータを追加する

Item::create([
    'name' => '鈴木',
    'age' => 25
]);

データの削除

全件削除
Item::get()->delete();
特定のデータのみ削除
Item::where('id', 2)->delete();
id指定で削除

idというカラムがある場合のみ使用可能

$id = 1;
Item::destroy($id);

複数削除できる

Item::destroy([1, 3]);

コントローラ記法

class コントローラ名 extends Controller
{
    public function 関数名()
    {
        // 処理
    }
}

web.phpでURLに変数を含めた場合、引数としてその変数を受け取ることができる。

class コントローラ名 extends Controller
{
    public function 関数名($変数名)
    {
        // 処理
    }
}

Viewの表示

Viewの名前はresources/views/からのパスを記述する。

return view("Viewの名前");

Viewにデータを渡す。

return view("Viewの名前", ['item' => $item]);

リダイレクト

web.phpのnameメソッドで指定した名前を入れる。

return redirect()->route('名前');

URLに変数がある場合

return redirect()->route('名前', ['item' => $item]);

formで送信されたデータの処理

$request->input()で取得可能

public function 関数名(Request $request)
{
     $name = $request->input('name');
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

テーブルからカラムの追加と削除をする方法(Laravel)

はじめに

今回も自分用のメモとしてアウトプットします。

・カラムの追加

1.migrationファイルの作成

例:postsテーブルにtagというカラムを追加したい場合

$ php artisan make:migration add_tag_to_posts_table --table=posts

上記の
:small_red_triangle:add_tag_to_posts_tableの部分は任意の命名で大丈夫です。
ですが、マイグレーションファイル名がそのままクラス名として生成されるので、できるだけわかりやすい名前をつけた方が良いです。

:small_red_triangle:--table=postsの部分では、カラムを追加するテーブルの指定を行なっています。

1のコマンドをターミナルで実行するとマイグレーションファイルが作成されます。

2.migrationファイルに記述の追加

upメソッドに追加の処理を記述します。

    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
                        $table->string('tag');
        });
    }

上記のような感じですね。

3.migrationの実行

$ php artisan migrate

こちらでテーブルにカラムの追加ができます。

・カラムの削除

こちらもカラムの追加と流れは似ています。

1.まずは、composer で “doctrine/dbal” パッケージを追加する必要があります。

$ composer require doctrine/dbal

2.migrationファイルの作成

例:postsテーブルのtagというカラムを削除したい場合

$ php artisan make:migration drop_column_tag_column --table=posts

こちらもカラムの追加と同様に、任意のファイル名とカラムを削除したいテーブルの指定をします。

3.migrationファイルに記述の追加

upメソッドに削除の処理を記述します。

    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropColumn('tag');
        });
    }

カラムを削除するには、スキーマビルダのdropColumnメソッドを使用します。
tagの部分は、削除したいカラム名に変更をお願いします。

4.migrationの実行

$ php artisan migrate

これでテーブルからカラムの削除ができます。

さいごに

初歩的ではありますが、自分の為にもアウトプットしました。
今回の記事で誤字、脱字等ありましたらお手数ですがご指摘をお願い致します。また、最後まで見て頂きありがとうございました!!

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

[初心者コピペ用]LaravelをAWSのEC2へデプロイ

前提

  • 2020年1月4日に確認したものです。
  • AWSのアカウント作成済
  • プロジェクトをGitHubにpush済

環境

  • macOS Catalina 10.15.2
  • Apache 2.4
  • PHP 7.1.33
  • MySQL 5.7
  • Laravel 5.8

1. EC2インスタンスの起動

  • EC2コンソールで作成(「公式チュートリアル」が分かりやすかったです)
  • 基本的に無料利用枠(下記の項目以外はデフォルト値)
設定項目 設定した内容
Amazon マシンイメージ (AMI) Amazon Linux 2でなく、Amazon Linux
インスタンスタイプ t2.micro
  • Linux2だと、手順が異なる公式ドキュメント

  • インスタンス作成の最後に、SSH接続に必要なキーペアを生成or設定

  • キーペア(pemファイル)は、~/.sshフォルダに入れておくと良い

2. EC2内で作業

2-1. SSHでEC2に接続

SSHとは. SSH(Secure Shell)とは、安全に通信を行って、ネットワークに接続された機器を遠隔操作するための通信手段(プロトコル)の1つ

※ 参照:初心者がSSHについて学ぶ(´・ω・`)

$ ssh -i [キーペア(pemファイル)を置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]
  • iオプションで、上記で生成or設定したpemファイルを指定する
  • ec2-userは、デフォルトのユーザー名。最初はこのユーザー名を使う
  • パブリックDNS or パブリックIPは、EC2コンソール画面で確認できる
  • 初回接続時のみ、yes/noを聞かれる

2-2. Apache, PHP, MySQLのインストール

  • yumのアップデートは忘れずに!(パッケージを最新にする)
  • yumはyオプションを付けることで、問い合わせ全てにYesと答えるため、yes/noがいちいち聞かれなくなります。
$ sudo yum update -y
$ sudo yum install -y httpd24 php71 php71-mbstring php71-zip php71-fpm php71-mysqlnd mysql57-server

Laravel 5.8のサーバ要件

2-3. Apacheを起動

$ sudo service httpd start

※ Linux2だと、systemctlコマンドが使える

この時点で、ブラウザでパブリック IPにアクセスすると、Apacheの画面が表示される。
EC2コンソール画面のセキュリティグループのインバウンドで、httpの80ポートを空けておくことを忘れずに
スクリーンショット 2020-01-04 18.42.21.png

# システムが再起動するたびにApacheが起動するように設定
$ sudo chkconfig httpd on

# 設定の確認
$ chkconfig --list httpd

2-4. ec2-userのファイル操作の許可を設定

参照:公式チュートリアル

Amazon Linux Apache ドキュメントルートは /var/www/html であり、デフォルトでは root によって所有されます。

そのため、ec2-userにファイル操作の権限を設定する必要がある。

# ec2-userをapacheグループに追加
$ sudo usermod -a -G apache ec2-user

# いったんログアウトして、再度ログイン
$ exit
$ ssh -i [キーペアのpemファイルを置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]

# /var/www とそのコンテンツのグループ所有権を apache グループに変更
$ sudo chown -R ec2-user:apache /var/www

# グループに、/var/wwwの書き込み許可追加
$ sudo chmod 2775 /var/www

# /var/www とサブディレクトのディレクトリ許可を変更
$ find /var/www -type d -exec sudo chmod 2775 {} \;

# /var/www とサブディレクトリのファイル許可を変更
$ find /var/www -type f -exec sudo chmod 0664 {} \;

2-5. composer自身のインストール

& curl -sS https://getcomposer.org/installer | php

# composerコマンドのパスを通す
$ sudo mv composer.phar /usr/local/bin/composer

# パス確認(/usr/local/bin/composerと表示されればOK)
$ which composer

2-6. Laravelプロジェクトをgit clone

sudo yum install git
cd /var/www
git clone [URL]

2-7. Apacheの設定変更

http.confファイルのDocumentRootの変更

Laravelでは、プロジェクト内のpublicディレクトリをドキュメントルートに指定する必要がある

$ sudo vi /etc/httpd/conf/httpd.conf

DocumentRoot “/var/www/html”の箇所をDocumentRoot “/var/www/プロジェクト名/public”に変更

http.confファイルに以下のDirectoryを追加(.htaccessの有効化)

<Directory /var/www/プロジェクト名/public>
 AllowOverride All
</Directory>

Apacheの設定変更後は、再起動を忘れずに!

$ sudo service httpd restart

2-8. パッケージのインストール

$ cd /var/www/[プロジェクトのフォルダ名]

# composer.jsonファイルがない場合
$ composer init

# vendorディレクトリが生成される
$ composer install

2-9. Laraveプロジェクトの設定

ディレクトリのパーミッション変更

Laravelでは、storage下とbootstrap/cacheディレクトリをWebサーバから書き込み可能にする必要がある

$ sudo chmod -R 777 /var/www/[プロジェクト名]/storage
$ sudo chmod -R 775 /var/www/[プロジェクト名]/bootstrap/cache

.envファイルの作成

cp .env.example .env

# .envファイルにある「APP_KEY」(アプリケーションキー)の生成
php artisan key:generate
APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:xxxxxxx(php artisan key:generateで生成される)
APP_DEBUG=false
APP_URL=http://[パブリックIP]

2-10. DBの設定、作成

MySQL側

# MySQL起動
$ sudo service mysqld start

# MySQLの初期設定
$ sudo mysql_secure_installation

# システムが再起動するたびにMySQLが起動するように設定
$ sudo chkconfig mysqld on

# データベース作成
$ mysql -u root -p
> 設定したパスワード入力
> create database [データベース名];
> show databases;
mysql_secure_installationコマンドで聞かれること
  • パスワード検証プラグインのセットアップ
  • パスワード
  • 匿名ユーザーアカウントの削除
  • rootユーザーのリモートログインの許否
  • testデータベースの削除

Laravel側

# 「DB_DATABASE」など、DB情報を設定しておく
$ sudo vi .env

DB_DATABASE=[作成したデータベース名]
DB_USERNAME=root
DB_PASSWORD=[設定したパスワード]
$ php artisan migrate
$ php artisan db:seed

参考にさせて頂いた記事

【Laravel】AWSにLaravelをインストールする
Laravel:EC2-PHP72-Apacheで環境を作成する
MySQL5.7 にて root のパスワード変更などの初期設定をする

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

LaravelをAWSのEC2へデプロイしてみた

前提

  • 2020年1月4日に確認したものです。
  • AWSのアカウント作成済
  • プロジェクトをGitHubにpush済

環境

  • macOS Catalina 10.15.2
  • Apache 2.4
  • PHP 7.1.33
  • MySQL 5.7
  • Laravel 5.8

1. EC2インスタンスの起動

  • EC2コンソールで作成(「公式チュートリアル」が分かりやすかったです)
  • 基本的に無料利用枠(下記の項目以外はデフォルト値)
設定項目 設定した内容
Amazon マシンイメージ (AMI) Amazon Linux 2でなく、Amazon Linux
インスタンスタイプ t2.micro
  • Linux2だと、手順が異なる公式ドキュメント

  • インスタンス作成の最後に、SSH接続に必要なキーペアを生成or設定

  • キーペア(pemファイル)は、~/.sshフォルダに入れておくと良い

2. EC2内で作業

2-1. SSHでEC2に接続

SSHとは. SSH(Secure Shell)とは、安全に通信を行って、ネットワークに接続された機器を遠隔操作するための通信手段(プロトコル)の1つ

※ 参照:初心者がSSHについて学ぶ(´・ω・`)

$ ssh -i [キーペア(pemファイル)を置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]
  • iオプションで、上記で生成or設定したpemファイルを指定する
  • ec2-userは、デフォルトのユーザー名。最初はこのユーザー名を使う
  • パブリックDNS or パブリックIPは、EC2コンソール画面で確認できる
  • 初回接続時のみ、yes/noを聞かれる

2-2. Apache, PHP, MySQLのインストール

  • yumのアップデートは忘れずに!(パッケージを最新にする)
  • yumはyオプションを付けることで、問い合わせ全てにYesと答えるため、yes/noがいちいち聞かれなくなります。
$ sudo yum update -y
$ sudo yum install -y httpd24 php71 php71-mbstring php71-zip php71-fpm php71-mysqlnd mysql57-server

Laravel 5.8のサーバ要件

2-3. Apacheを起動

$ sudo service httpd start

※ Linux2だと、systemctlコマンドが使える

この時点で、ブラウザでパブリック IPにアクセスすると、Apacheの画面が表示される。
EC2コンソール画面のセキュリティグループのインバウンドで、httpの80ポートを空けておくことを忘れずに
スクリーンショット 2020-01-04 18.42.21.png

# システムが再起動するたびにApacheが起動するように設定
$ sudo chkconfig httpd on

# 設定の確認
$ chkconfig --list httpd

2-4. ec2-userのファイル操作の許可を設定

参照:公式チュートリアル

Amazon Linux Apache ドキュメントルートは /var/www/html であり、デフォルトでは root によって所有されます。

そのため、ec2-userにファイル操作の権限を設定する必要がある。

# ec2-userをapacheグループに追加
$ sudo usermod -a -G apache ec2-user

# いったんログアウトして、再度ログイン
$ exit
$ ssh -i [キーペアのpemファイルを置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]

# /var/www とそのコンテンツのグループ所有権を apache グループに変更
$ sudo chown -R ec2-user:apache /var/www

# グループに、/var/wwwの書き込み許可追加
$ sudo chmod 2775 /var/www

# /var/www とサブディレクトのディレクトリ許可を変更
$ find /var/www -type d -exec sudo chmod 2775 {} \;

# /var/www とサブディレクトリのファイル許可を変更
$ find /var/www -type f -exec sudo chmod 0664 {} \;

2-5. composer自身のインストール

& curl -sS https://getcomposer.org/installer | php

# composerコマンドのパスを通す
$ sudo mv composer.phar /usr/local/bin/composer

# パス確認(/usr/local/bin/composerと表示されればOK)
$ which composer

2-6. Laravelプロジェクトをgit clone

sudo yum install git
cd /var/www
git clone [URL]

2-7. Apacheの設定変更

http.confファイルのDocumentRootの変更

Laravelでは、プロジェクト内のpublicディレクトリをドキュメントルートに指定する必要がある

$ sudo vi /etc/httpd/conf/httpd.conf

DocumentRoot “/var/www/html”の箇所をDocumentRoot “/var/www/プロジェクト名/public”に変更

http.confファイルに以下のDirectoryを追加(.htaccessの有効化)

<Directory /var/www/プロジェクト名/public>
 AllowOverride All
</Directory>

Apacheの設定変更後は、再起動を忘れずに!

$ sudo service httpd restart

2-8. パッケージのインストール

$ cd /var/www/[プロジェクトのフォルダ名]

# composer.jsonファイルがない場合
$ composer init

# vendorディレクトリが生成される
$ composer install

2-9. Laraveプロジェクトの設定

ディレクトリのパーミッション変更

Laravelでは、storage下とbootstrap/cacheディレクトリをWebサーバから書き込み可能にする必要がある

$ sudo chmod -R 777 /var/www/[プロジェクト名]/storage
$ sudo chmod -R 775 /var/www/[プロジェクト名]/bootstrap/cache

.envファイルの作成

cp .env.example .env

# .envファイルにある「APP_KEY」(アプリケーションキー)の生成
php artisan key:generate
APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:xxxxxxx(php artisan key:generateで生成される)
APP_DEBUG=false
APP_URL=http://[パブリックIP]

2-10. DBの設定、作成

MySQL側

# MySQL起動
$ sudo service mysqld start

# MySQLの初期設定
$ sudo mysql_secure_installation

# システムが再起動するたびにMySQLが起動するように設定
$ sudo chkconfig mysqld on

# データベース作成
$ mysql -u root -p
> 設定したパスワード入力
> create database [データベース名];
> show databases;
mysql_secure_installationコマンドで聞かれること
  • パスワード検証プラグインのセットアップ
  • パスワード
  • 匿名ユーザーアカウントの削除
  • rootユーザーのリモートログインの許否
  • testデータベースの削除

Laravel側

# 「DB_DATABASE」など、DB情報を設定しておく
$ sudo vi .env

DB_DATABASE=[作成したデータベース名]
DB_USERNAME=root
DB_PASSWORD=[設定したパスワード]
$ php artisan migrate
$ php artisan db:seed

参考にさせて頂いた記事

【Laravel】AWSにLaravelをインストールする
Laravel:EC2-PHP72-Apacheで環境を作成する
MySQL5.7 にて root のパスワード変更などの初期設定をする

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

LaravelをAWSのEC2へデプロイする手順

前提

  • 2020年1月4日に確認したものです。
  • AWSのアカウント作成済
  • プロジェクトをGitHubにpush済

環境

  • macOS Catalina 10.15.2
  • Apache 2.4
  • PHP 7.1.33
  • MySQL 5.7
  • Laravel 5.8

1. EC2インスタンスの起動

  • EC2コンソールで作成(「公式チュートリアル」が分かりやすかったです)
  • 基本的に無料利用枠(下記の項目以外はデフォルト値)
設定項目 設定した内容
Amazon マシンイメージ (AMI) Amazon Linux 2でなく、Amazon Linux
インスタンスタイプ t2.micro
  • Linux2だと、手順が異なる公式ドキュメント

  • インスタンス作成の最後に、SSH接続に必要なキーペアを生成or設定

  • キーペア(pemファイル)は、~/.sshフォルダに入れておくと良い

2. EC2内で作業

2-1. SSHでEC2に接続

SSHとは. SSH(Secure Shell)とは、安全に通信を行って、ネットワークに接続された機器を遠隔操作するための通信手段(プロトコル)の1つ

※ 参照:初心者がSSHについて学ぶ(´・ω・`)

$ ssh -i [キーペア(pemファイル)を置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]
  • iオプションで、上記で生成or設定したpemファイルを指定する
  • ec2-userは、デフォルトのユーザー名。最初はこのユーザー名を使う
  • パブリックDNS or パブリックIPは、EC2コンソール画面で確認できる
  • 初回接続時のみ、yes/noを聞かれる

2-2. Apache, PHP, MySQLのインストール

  • yumのアップデートは忘れずに!(パッケージを最新にする)
  • yumはyオプションを付けることで、問い合わせ全てにYesと答えるため、yes/noがいちいち聞かれなくなります。
$ sudo yum update -y
$ sudo yum install -y httpd24 php71 php71-mbstring php71-zip php71-fpm php71-mysqlnd mysql57-server

Laravel 5.8のサーバ要件

2-3. Apacheを起動

$ sudo service httpd start

※ Linux2だと、systemctlコマンドが使える

この時点で、ブラウザでパブリック IPにアクセスすると、Apacheの画面が表示される。
EC2コンソール画面のセキュリティグループのインバウンドで、httpの80ポートを空けておくことを忘れずに
スクリーンショット 2020-01-04 18.42.21.png

# システムが再起動するたびにApacheが起動するように設定
$ sudo chkconfig httpd on

# 設定の確認
$ chkconfig --list httpd

2-4. ec2-userのファイル操作の許可を設定

参照:公式チュートリアル

Amazon Linux Apache ドキュメントルートは /var/www/html であり、デフォルトでは root によって所有されます。

そのため、ec2-userにファイル操作の権限を設定する必要がある。

# ec2-userをapacheグループに追加
$ sudo usermod -a -G apache ec2-user

# いったんログアウトして、再度ログイン
$ exit
$ ssh -i [キーペアのpemファイルを置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]

# /var/www とそのコンテンツのグループ所有権を apache グループに変更
$ sudo chown -R ec2-user:apache /var/www

# グループに、/var/wwwの書き込み許可追加
$ sudo chmod 2775 /var/www

# /var/www とサブディレクトのディレクトリ許可を変更
$ find /var/www -type d -exec sudo chmod 2775 {} \;

# /var/www とサブディレクトリのファイル許可を変更
$ find /var/www -type f -exec sudo chmod 0664 {} \;

2-5. composer自身のインストール

& curl -sS https://getcomposer.org/installer | php

# composerコマンドのパスを通す
$ sudo mv composer.phar /usr/local/bin/composer

# パス確認(/usr/local/bin/composerと表示されればOK)
$ which composer

2-6. Laravelプロジェクトをgit clone

sudo yum install git
cd /var/www
git clone [URL]

2-7. Apacheの設定変更

http.confファイルのDocumentRootの変更

Laravelでは、プロジェクト内のpublicディレクトリをドキュメントルートに指定する必要がある

$ sudo vi /etc/httpd/conf/httpd.conf

DocumentRoot “/var/www/html”の箇所をDocumentRoot “/var/www/プロジェクト名/public”に変更

http.confファイルに以下のDirectoryを追加(.htaccessの有効化)

<Directory /var/www/プロジェクト名/public>
 AllowOverride All
</Directory>

Apacheの設定変更後は、再起動を忘れずに!

$ sudo service httpd restart

2-8. パッケージのインストール

$ cd /var/www/[プロジェクトのフォルダ名]

# composer.jsonファイルがない場合
$ composer init

# vendorディレクトリが生成される
$ composer install

2-9. Laraveプロジェクトの設定

ディレクトリのパーミッション変更

Laravelでは、storage下とbootstrap/cacheディレクトリをWebサーバから書き込み可能にする必要がある

$ sudo chmod -R 777 /var/www/[プロジェクト名]/storage
$ sudo chmod -R 775 /var/www/[プロジェクト名]/bootstrap/cache

.envファイルの作成

cp .env.example .env

# .envファイルにある「APP_KEY」(アプリケーションキー)の生成
php artisan key:generate
APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:xxxxxxx(php artisan key:generateで生成される)
APP_DEBUG=false
APP_URL=http://[パブリックIP]

2-10. DBの設定、作成

MySQL側

# MySQL起動
$ sudo service mysqld start

# MySQLの初期設定
$ sudo mysql_secure_installation

# システムが再起動するたびにMySQLが起動するように設定
$ sudo chkconfig mysqld on

# データベース作成
$ mysql -u root -p
> 設定したパスワード入力
> create database [データベース名];
> show databases;
mysql_secure_installationコマンドで聞かれること
  • パスワード検証プラグインのセットアップ
  • パスワード
  • 匿名ユーザーアカウントの削除
  • rootユーザーのリモートログインの許否
  • testデータベースの削除

Laravel側

# 「DB_DATABASE」など、DB情報を設定しておく
$ sudo vi .env

DB_DATABASE=[作成したデータベース名]
DB_USERNAME=root
DB_PASSWORD=[設定したパスワード]
$ php artisan migrate
$ php artisan db:seed

参考にさせて頂いた記事

【Laravel】AWSにLaravelをインストールする
Laravel:EC2-PHP72-Apacheで環境を作成する
MySQL5.7 にて root のパスワード変更などの初期設定をする

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

【おうちハック】開発合宿で3人でシェアハウスの鍵管理システムを作った【チーム開発】

こんにちわ。れとるときゃりー(@retoruto_carry)です。

私が住んでいるシェアハウスの同居人たちで、去年の7月に開発合宿に行きました。

そのときに @wamisnet@fukubaka0825 と作った、シェアハウスの鍵管理システムが先日完成したので紹介します。

全体の流れと、自分の担当した領域について解説します。

作ったもの

鍵を開けるデバイス

@wamisnet@fukubaka0825 が担当

Image

こちらに関して、各自の記事があるので、後ほど是非合わせてお読みください!

Raspberry pi とGoとMackerelでシェアハウスの運用しやすい鍵システムを作る - Qiita
Suicaで開けられるスマートロックを作ってみた - Qiita

ICカードの管理システム

私が担当しました。
本記事で詳しく解説します

  • ユーザー(住人)を追加 Image

ICカードを追加
Image

ICカードと住人の削除もできます

システム構成図

image.png

開発のきっかけ

ファイル名

  • 「いちいちスマホアプリで操作するのがめんどくさいよね」
    • 開けるの5秒くらいかかります
  • 「ICカードで入れたら、楽じゃね?」
  • 「お、それ作ろうぜ」

何をしたか

仕様の決定

家の中で雑談から、企画と設計がその場のノリで始まりました。
Image

その場で仕様を紙に書きはじめました。

3人ですり合わせていきました。
Image

3人のイメージを合わせるために絵とかも書いています。

見にくいので、雰囲気だけ感じてくださいw

DB設計

Image

画面設計

このあたりは私の得意領域なので、私が中心になって考えたました。

Image
Image
Image
Image

途中で出前でピザを注文したりして、楽しかったです。
Image

家に貼ってみたらめっちゃ頑張った感ありました。
Image

続きは、一ヶ月後にシェアハウス全体で開催する、開発合宿で行おうということになりました。

開発合宿

箱根でゲストハウスを借りて、3日間行いました。

Image

一日観光したので、作業時間は2日間
Image

自分のやったこと

私の担当箇所

ICカードの情報の管理システムを作りました
Image

できること

  • 住人を登録する
  • ICカードを追加したり削除したりする
  • イベントを発行して、一時的なQRコードの鍵を発行できる(未実装)

構成

  • ラズパイ
  • nginx
  • Laravel
  • Nuxt.js
  • Mysql
  • Unbound

Image

やったこと

インフラを作成

インフラを整えるのに1日半かかりました?

Unboundを使って、お家DNSサーバーを立てた

作業メモ → お家でラズパイを使ってDNSサーバーを作ってみる

家のwifiに接続しているときは、「key.home」にアクセスすると、ラズパイのサーバに接続するようになります
Image

ラズパイにnginx、mysql、php、laravel、nuxt.jsを入れた

作業メモ → ラズパイでサーバーを立てる

Image
Image

そもそもこのとき、nginxを初めて触ったのでめっちゃ詰まりました。

アプリを作成

アプリは、残り半日で雑に突貫で作りました

設計をもとにAPI(Laravel)を作成
  • APIリソース を使うと簡潔にかけました
  • -rオプションを使うと、Resourcefulなアクションを自動で定義したコントローラーを生成してくれます。 時短になります。
bash
$ php artisan make:controller HogeController -r
設計をもとにフロント(nuxt.js)を作成

採用技術

  • moment
    • 日付の計算に使用
  • buefy
    • UIフレームワーク

最後はみんなで発表しあって、合宿は終了

  • Image

感想

  • 開発合宿楽しい
  • チーム開発楽しい

最初に、仕様を決めて、担当範囲を切り分けて、インターフェースを決めておいたのがとても良かったです。
実装中のコミュニケーションがほとんど必要なく、各自が黙々と作業をすすめることが出来ました。

ツイートにも書いてありますが、普段は仮想サーバーでサービスを運用しているので、実機で運用するサービスを作ってみたかったのです。
実際に、今現在、シェアハウス内で運用されています。
物理的にものがあると、実感が湧きます。とても満足しています。

今後やりたいこと

  • 適当に作ったせいで、UIがわかりにくいので、ユーザーフレンドリーにしたいです
      • ユーザーやICカードの追加のボタンの位置を調整
      • 説明をトップページに乗せる

ここまで読んでくれた方へ

ここまで読んでくださりありがとうございます。

他のメンバーが自分の担当した領域を解説した記事があるので、是非あわせてお読みください!

@fukubaka0825 【担当】Suica認証、Sesame開錠指示
Raspberry pi とGoとMackerelでシェアハウスの運用しやすい鍵システムを作る - Qiita

@wamisnet【担当】Sesame開錠デバイス作成、ハードウエア
Suicaで開けられるスマートロックを作ってみた - Qiita

いいねやコメント、SNSでの共有等をしてくださると、今後の励みになります。よろしくお願いします。

良かったらツイッター(@retoruto_carry)もフォローしてね

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

【Laravel】laravelでユーザー管理(ログイン、新規登録)、ファイルのアップロード機能の実装

作成にあたって、参考にしたサイト
laravle学習帳

要件定義

ユーザー管理機能(新規登録、ログイン)を実装。

ログインしたら
画像投稿、投稿画像一覧の機能が使えるようにする。

その他
・ログインしているユーザーidと投稿画像のidを紐つけて、どのユーザーが投稿したか管理する。

データベース設計

  • プロジェクト名:laravel_fileup
  • 画像投稿のモデル、テーブルはPost、postsとする
     

    postsテーブルのカラム設計

  • id

  • tile:画像のタイトル

  • path:画像の保存先のパス

  • user_id:どのユーザーが投稿したかのため

usersテーブルのカラム設計

こちらは自動で作成されるので割愛

プロジェクトの作成

$ composer create-project --prefer-dist laravel/laravel='5.8' laravel_fileup

.envファイルの編集

database.sqliteの作成

ログイン機能の実装

make::authを使う

$ php artisan make:auth

ログイン時とログアウト時の遷移先を変更する

参考記事:https://qiita.com/LowSE01/items/ffa256439f665740cc8f

app/Http/controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

+ use Illuminate\Http\Request;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
+    protected $redirectTo = '/posts/create';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

+    public function logout(Request $request)
+   {
+       $this->guard()->logout();
+       $request->session()->flush();
+       $request->session()->regenerate();

+       return redirect('/login');//ログアウト時の遷移先
+  }

}

fileのアップロード用モデルとマイグレーションを作成

$ php artisan make:model Post -m
Model created successfully.
Created Migration: 2019_12_30_005951_create_posts_table

migrationファイルの修正(タイトルとパスのカラムを作成)

database/migrations/2019_12_30_005951_create_posts_table.php
            $table->bigIncrements('id');
+           $table->unsignedInteger('user_id');
+           $table->string('title');
+           $table->text('path');
            $table->timestamps();
+           $table->foreign('user_id')->references('id')->on('users');

マイグレーションの実行

$ php artisan migrate

Post.php(ポストモデルの修正)

postsテーブルへの書き込み権限を付与
Userモデルとの紐付けを記載

app/Post.php
class Post extends Model
{
+    protected $fillable = ['title','path'];

+    public function user() {
+    return $this->belongTo('App\User');}

Userモデルの修正

Postモデルとの紐付けを記載

app/User.php
+  public function posts() {
+    return $this->hasMany('App\Post');
+    }

ファイルのアップロード等を管理するコントローラーの作成

$ php artisan make:controller PostsController
Controller created successfully.

ファイル操作に関連するroutesを作成

参考記事
https://qiita.com/sympe/items/9297f41d5f7a9d91aa11

routes/web.php
// Route::get('/', function () {return view('welcome');});
Auth::routes();
// Route::get('/home', 'HomeController@index')->name('home');
+ Route::resources('posts','PostsController');

新規投稿〜画像保存までの流れを作成

ファイルアップロード用のフォームを作成

resources/views/posts/create.blade.php
@extends('layouts.app')

@section('content')

<div class="container">
  <form method="post" action="/posts" enctype="multipart/form-data">
    {{ csrf_field() }}
  <div class="form-group">
  <label>投稿する画像のタイトルを入力してください</label>
  <input type="text" name="title" class="form-control col-sm-4" value="{{ old('title')}}">
  </div>

  <div class="form-group">
  <label>投稿する画像を選んでください</label>
    <input type="file" id="file" name="file" class="form-control col-sm-4">
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-primary">アップロード</button>
  </div>
    </form>

  @if ($errors->has('title'))
  <div class="alert alert-danger" role="alert">{{$errors->first('title')}}</div>
  @endif


  @if ($errors->has('file'))
  <div class="alert alert-danger" role="alert">{{$errors->first('file')}}</div>
  @endif


  @if (session('flash_message'))
  <div class="alert alert-success" role="alert">{{ session('flash_message')}}</div>
  @endif

</div>


@endsection

コントローラーの設定

app
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
use App\User;
use App\Http\Requests\CreatePostRequest;
use Carbon\Carbon;

class PostsController extends Controller
{
    //ログインしていないと、PostsController内の処理ができないようにする。
    public function __construct() {
      $this->middleware('auth');
    }

    public function index() {
      $posts = Post::all();
      return view('posts.index')->with('posts',$posts);
    }

    public function create() {
      return view('posts.create');
    }

    public function store(CreatePostRequest $request) {
            $nowtime = Carbon::now();
      //ログインしているユーザーを取得
      $user = Auth::user();
      //ファイル名取得
      $filename = $user->id . "_".$nowtime."_". $request->file('file')->getClientOriginalName();
      //storage/app/publicにファイルを保存する
      $request->file('file')->storeAs('public',$filename);

      $post = new Post();
      $post->title = $request->title;
      $post->path = '/storage/'.$filename;
      $user->posts()->save($post);
      session()->flash('flash_message', '投稿が完了しました');
      return redirect('posts/create');
    }
}

バリデーションの設定をする。

バリデーション用のファイルを作成する。

$ php artisan make:request CreatePostRequest
Request created successfully.

CreatePostRequestを編集する。

app/Http/Request/CreatePostRequest.php
    public function rules()
    {
        return [
+         'title' => 'required',
+         'file' => 'required|image',
        ];
    }

+    public function messages() {
+    return [
+       'title.required' => 'タイトルが入力されていません',
+        'file.required' => '画像を選択してください',
+        'file.image' => '画像ファイルを選択してください',
+    ];

コントローラーに適用する

作成したCreatePostRequestを読み込む
store()メソッドの引数に入れる。

app/Http/controllers/PostsController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
use App\User;
+ use App\Http\Requests\CreatePostRequest;
use Carbon\Carbon;




+ public function store(CreatePostRequest $request) {

シンボリックリンクの作成

$ php artisan storage:link
The [public/storage] directory has been linked.

取得した画像をの一覧表示を実装する。

・やりたいこと画像のタイトルと画像の表示

resources/views/posts/index.blade.php
@extends('layouts.app')

@section('content')

<div class="container">
  <div class="row">
    @foreach($posts as $post)
    <div class="col-md-3" style="margin-top:10px;">
      <img src="{{$post->path}}" width="95%">
    <h3 style="margin-top:3px;text-align:center;">タイトル{{ $post->title}}</h3>
  </div>
    @endforeach
</div>

@endsection

編集モードにて削除コマンドをつける

editメソッドの作成

index.blade.phpに編集モードへのリンクを作成

resources/views/posts/index.blade.php
    @foreach($posts as $post)
    <div class="col-md-3" style="margin-top:10px;">
+      <a href="{{ action('PostsController@edit',$post) }}"><img src="{{$post->path}}" width="95%"></a>
    <h3 style="margin-top:3px;text-align:center;">{{ $post->title}}</h3>
  </div>
    @endforeach

PostsControlerのeditメソッドを作成

app/Http/Controllers/PostsController.php
    public function edit(Post $post) {
      return view('posts.edit')->with('post',$post);
    }

編集ビューの作成
編集ビューに削除ボタン作成

resources/views/posts/edit.blade.php
@extends('layouts.app')

@section('content')

<div class="container">
  <div>
  <img src="{{$post->path}}" width="80%">
  </div>


  <form action="{{ action('PostsController@destroy',$post)}}" method="post">
  {{csrf_field()}}
  {{method_field('delete')}}
      <div class="row" style="margin-top:30px;">
    <button type="submit" class="btn btn-danger col-sm-3">削除する</button>
    </div>
  </form>

</div>

@endsection

PostsControllerにdestroyメソッド(削除メソッド)作成

app/Http/controllers/PostsCotnroller.php
public function destroy(Post $post) {
      $post->delete();
      session()->flash('flash_message', '投稿画像を削除しました');
      return redirect('/');
    }

auth関連で作成したビューを日本語化する

参考記事
https://qiita.com/miya-krow/items/05170462b2f092c95dfa

config/appを変更する

config/app.php
'locale' => 'ja',
'fallback_locale' => 'ja',

en:Engilish
ja:Japanese

ja.jsonファイルを作成して対応する

$ vi resources/lang/ja.json
resources/lang/ja.json
{  "Login"    :"ログイン",
   "Register" :"新規登録",
   "Password" : "パスワード",
   "E-Mail Address": "メールアドレス",
   "Logout":"ログアウト",
   "Name": "ニックネーム",
   "Confirm Password": "パスワード(もう一度入力)"
}

その他

パスワードリセット機能は実装しないので、使えないようにする。

対象部をコメントアウトする

resources/views/auth/login.blade.php
                        <!-- <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div> -->

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                <!-- @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif -->
                            </div>

urlに直接入力してら、indexに飛ばすようにする。

routes/web.php
Route::get('/', 'PostsController@index');
Auth::routes();
+ Route::get('/password/email', function() {return redirect('/');});
+ Route::get('/password/reset', function() {return redirect('/');});
// Route::get('/home', 'HomeController@index')->name('home');
Route::resource('posts','PostsController');

以上です。

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

Laravel 6 で laravel/ui をインストールしたらwebpackがコンパイルできなかった

前提

Laravel 6 から、認証機能を使うためには laravel/ui を追加インストールしなければいけなくなった。

公式ドキュメント

公式ドキュメントだとwebpackのコンパイルに関しては書かれておらず、UIを適用するには、以下のコマンドを実行する必要がある。

$ npm install
$ npm run dev

参考: https://www.techiediaries.com/laravel-authentication-tutorial/

エラー

実行しようとしたら、エラーが出た。

npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js`

どうやら、以下が問題となっているらしい。

Error: Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (72)

調べていくと、 node-sass を再インストールすればいいらしい。
が、 npm install -g node-sass で、再度エラー。

Error: EACCES: permission denied, mkdir /Users/xxx/node_modules/node-sass/build

権限関係ならと思い、 sudo してもだめ。
これは、そもそも npmをsudoでインストールしている と出てしまうらしい(?ちゃんと理解できてないかも?)

参照
Error: EACCES, mkdir '/usr/local/lib/node_modules/node-sass' - installing globally #1098 へのコメント
Resolving EACCES permissions errors when installing packages globally

解決方法

node バージョンマネージャーである nvm をインストールして、そこから改めて node をインストールする。
すでに npmsudo でダウンロードされていても大丈夫。

Github: nvm

nvm のインストール

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash

~/.bash_profile などに以下を追加

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

node-sass のインストール

npm install -g node-sass

コンパイル成功

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

Laravelで簡単なメモアプリを作る(3)~データの更新と削除~

はじめに

Laravelとは、Webに特化したPHPフレームワーク。セキュリティ対策(CSRF対策など)もこれでできます。MVCアーキテクチャを採用しています。今回は、データの更新と削除をしていきたいと思います。

Laravelで簡単なメモアプリを作る(1)~Viewの作成と表示~
Laravelで簡単なメモアプリを作る(2)~データの取得と保存~

今回の目標物

スクリーンショット 2019-12-31 11.25.14.png

スクリーンショット 2019-12-31 11.25.26.png

データの更新

更新するデータの取得

id=1のデータを取得する時は、このように書く。

$memo = Memo::find(1);

whereメソッドでも、取得することができる。ただ、whereメソッドは、findメソッドと異なって、条件に合うものを全て取ってくるため、たとえ条件に合うものが一つであったとしても配列として取得するので注意。なのでfirstメソッドで、要素として取得する必要がある。

$memo = Memo::where('id', 1)->first();

データの更新

updateメソッドで、データベース上のデータを書き換えることができる。

$memo->update([
    'title' => $title,
    'content' => $content
]);

MemoControllerを以下のように編集する。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit($id = 0)
    {
        if ($id != 0) {
            $memo = Memo::where('id', $id)->get()->first();
        } else {
            $memo = (object) ["id" => 0, "title" => "", "content" => ""];
        }
        return view("submit", ['memo' => $memo]);
    }

    public function postSubmit(Request $request, $id = 0)
    {
        $title = $request->input('title');
        $content = $request->input('content');
        if ($id == 0) {
            Memo::create([
                'title' => $title,
                'content' => $content
            ]);
        } else {
            $memo = Memo::find($id);
            $memo->update([
                'title' => $title,
                'content' => $content
            ]);
        }
        return redirect()->route('home');
    }
}

データの削除

メモを削除する関数の作成

destroyメソッドを使うと、引数に指定したidのデータだけが削除される。下のコードをMemoControllerに追加する。

public function deleteMemo($id)
{
    Memo::destroy($id);
    return redirect()->route('home');
}

web.phpにdeleteMemoメソッドの登録

/delete/{id}というURLを受け取ったら、メモが削除されるようにする。下のコードをweb.phpに追加する。

Route::get('/delete/{id}', 'MemoController@deleteMemo')->name('delete');

削除ボタンを押したら削除されるようにする

resources/views/home.blade.phpの削除ボタンを以下のように修正する。

<td><a href="{{ route('delete', ['id' => $memo->id])}}">削除</a></td>

おまけ

モーダルを使って、削除の確認をする

bootstrap4のモーダルを使用する。
https://getbootstrap.com/docs/4.3/components/modal/

resources/views/home.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        color: white;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .card {
        margin-top: 40px;
    }

    .left {
        width: 70%;
    }

    .submit {
        position: absolute;
        top: 10px;
        right: 20px;
    }
</style>
@endsection

@section('content')
<div class="card" style="width: 100%;">
    <div class="card-header">
        メモ一覧
        <a href="{{ route('submit')}}" class="submit">メモを追加</a>
    </div>

    <table class="table">
        <tbody>
            @foreach ($memos as $memo)
            <tr>
                <td class="left">{{$memo->title}}</td>
                <td><a href="{{ route('submit', ['id' => $memo->id])}}">編集</a></td>
                <td><a type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">削除</a></td>
            </tr>
            <!-- Modal -->
            <div class="modal fade" id="modal{{$memo->id}}" tabindex="-1" role="dialog" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">以下のメモを本当に削除しますか?</h5>
                            <button type="button" class="close" data-dismiss="modal">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            {{$memo->title}}
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
                            <button type="button" class="btn btn-primary"
                                onclick="location.href='{{ route('delete', ['id' => $memo->id])}}'">
                                削除
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

submitページのボタンを新規作成の時と編集の時で変える

新規作成の時は$memo->id == 0で、編集の時は$memo->id != 0なので、if文で条件分岐する。
resources/views/submit.blade.phpの追加ボタンを以下のように書き換える。

@if($memo->id == 0)
<button type="submit" class="btn btn-success">追加</button>
@else
<button type="submit" class="btn btn-success">適用</button>
@endif

テーブルの列をクリックしたら、詳細画面に飛べるようにする

下のコードを、app.blade.phpのbodyタグの一番下に追加する。

resources/views/layouts/app.blade.php
<script>
    jQuery(function($) {
                $('tbody tr[data-href]').addClass('clickable').click(function() {
                    window.location = $(this).attr('data-href');
                }).find('a').hover(function() {
                    $(this).parents('tr').unbind('click');
                }, function() {
                    $(this).parents('tr').click( function() {
                        window.location = $(this).attr('data-href');
                    });
                });
            });
</script>

home.blade.phpの編集ボタンを消して、trタグにdata-href属性を追加する。

resources/views/home.blade.php
<tr data-href="{{route('submit', ['id' => $memo->id])}}">
       <td class="left">{{$memo->title}}</td>
       <td><a type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">削除</a></td>
</tr>

テーブルの列をホバーすると色が変わるようにする

trタグにclass="table-row"を追加する。

resources/views/home.blade.php
<tr data-href="{{route('submit', ['id' => $memo->id])}}" class="table-row">
       <td class="left">{{$memo->title}}</td>
       <td><a type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">削除</a></td>
</tr>
resources/views/home.blade.php
.table-row {
    background-color: #fff;
}

.table-row:hover {
    background-color: #ddd;
}

追加ボタンをいい感じにする。ヘッダーも固定する。

app.blade.phpでFont Awesomeを読み込む。

resources/views/layouts/app.blade.php
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">

app.blade.phpを以下のように編集する。

resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>MemoApp</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css"
        integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" crossorigin="anonymous">
    <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous">
    </script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/js/bootstrap.min.js"
        integrity="sha384-3qaqj0lc6sV/qpzrc1N5DC6i1VRn/HyX4qdPaiEFbn54VjQBEU341pvjz7Dv3n6P" crossorigin="anonymous">
    </script>
</head>

<style>
    header {
        background-color: #000;
        background-position: 0px 50px;
        padding-left: 20px;
        font-size: large;
        width: 100%;
        height: 50px;
        clear: both;
        position: fixed;
        top: 0;
        margin-top: 0px;
        z-index: 1;
    }

    .title {
        position: absolute;
        top: 10px;
        color: #fff;
    }

    .container {
        margin-top: 70px;
    }
</style>

@yield('css')

<body>
    <header>
        <span class="title">MemoApp</span>
    </header>

    <div class="container">
        @yield('content')
    </div>

    <script>
        jQuery(function($) {
                $('tbody tr[data-href]').addClass('clickable').click(function() {
                    window.location = $(this).attr('data-href');
                }).find('a').hover(function() {
                    $(this).parents('tr').unbind('click');
                }, function() {
                    $(this).parents('tr').click( function() {
                        window.location = $(this).attr('data-href');
                    });
                });
            });
    </script>
</body>

</html>

home.blade.phpを以下のように編集する。

resources/views/home.blade.php
@extends('layouts.app')

@section('css')
<style>
    .table-row {
        background-color: #fff;
    }

    .table-row:hover {
        background-color: #ddd;
    }

    .card {
        margin-top: 40px;
    }

    .circle-button {
        position: fixed;
        display: inline-block;
        text-decoration: none;
        color: rgba(152, 152, 152, 0.43);
        width: 80px;
        height: 80px;
        line-height: 80px;
        font-size: 40px;
        border-radius: 50%;
        text-align: center;
        overflow: hidden;
        font-weight: bold;
        background-image: linear-gradient(#e8e8e8 0%, #d6d6d6 100%);
        text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.66);
        box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 2px 2px rgba(0, 0, 0, 0.19);
        border-bottom: solid 2px #b5b5b5;
    }

    .circle-button i {
        line-height: 80px;
    }

    .circle-button:active {
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 2px rgba(0, 0, 0, 0.19);
        border-bottom: none;
    }

    @media screen and (min-width:0px) {
        .circle-button {
            bottom: 20px;
            right: 30px;
        }
    }

    @media screen and (min-width:768px) and (max-width:1024px) {
        .circle-button {
            bottom: 20px;
            right: 50px;
        }
    }

    @media screen and (min-width:1024px) {
        .circle-button {
            bottom: 30px;
            right: 150px;
        }
    }

    .delete-button {
        display: inline-block;
        text-decoration: none;
        width: 20px;
        height: 20px;
        line-height: 20px;
        font-size: 7px;
        border-radius: 50%;
        text-align: center;
        overflow: hidden;
        background-color: #cd5c5c;
        margin-right: 10px;
        margin-top: 5px;
    }

    .delete-button i {
        line-height: 20px;
        color: #fff;
    }

    .td-left {
        width: 10px;
    }
</style>
@endsection

@section('content')
<div class="card" style="width: 100%;">
    <div class="card-header">
        メモ一覧
    </div>

    <table class="table">
        <tbody>
            @foreach ($memos as $memo)
            <tr data-href="{{route('submit', ['id' => $memo->id])}}" class="table-row">
                <td class="td-left">
                    <a class="delete-button" type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">
                        <i class="fa fa-minus"></i>
                    </a>
                </td>
                <td class="td-right">
                    {{$memo->title}}
                </td>
            </tr>
            <!-- Modal -->
            <div class="modal fade" id="modal{{$memo->id}}" tabindex="-1" role="dialog" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">以下のメモを本当に削除しますか?</h5>
                            <button type="button" class="close" data-dismiss="modal">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            {{$memo->title}}
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
                            <button type="button" class="btn btn-primary"
                                onclick="location.href='{{ route('delete', ['id' => $memo->id])}}'">
                                削除
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            @endforeach
        </tbody>
    </table>
</div>

<a href="{{route('submit')}}" class="circle-button">
    <i class="fa fa-plus"></i>
</a>

@endsection

submit.blade.phpのcss部分を消しておく。inputもついでに文字数制限をかける。

resources/views/submit.blade.php
@extends('layouts.app')

@section('content')
<form method="POST" action="{{ route('submit', ['id' => $memo->id])}}">
    @csrf
    <div class="form-group">
        <label for="title">タイトル</label>
        <input type="text" class="form-control" id="title" name="title" value="{{$memo->title}}" maxlength="24"
            required>
    </div>
    <div class="form-group">
        <label for="content">内容</label>
        <input type="text" class="form-control" id="content" name="content" value="{{$memo->content}}" maxlength="60"
            required>
    </div>
    <a href="{{ route('home')}}" class="btn btn-primary">戻る</a>
    @if($memo->id == 0)
    <button type="submit" class="btn btn-success">追加</button>
    @else
    <button type="submit" class="btn btn-success">適用</button>
    @endif
</form>
@endsection

スクリーンショット 2020-01-04 23.29.44.png

今回はここまで。次回は、ログイン機能を実装します。

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

Laravelで簡単なメモアプリを作る(3)~データの編集と削除~

はじめに

Laravelとは、Webに特化したPHPフレームワーク。セキュリティ対策(CSRF対策など)もこれでできます。MVCアーキテクチャを採用しています。今回は、データの編集と削除をしていきたいと思います。

Laravelで簡単なメモアプリを作る(1)~Viewの作成と表示~
Laravelで簡単なメモアプリを作る(2)~データの取得と保存~

今回の目標物

スクリーンショット 2019-12-31 11.25.14.png

スクリーンショット 2019-12-31 11.25.26.png

データの編集

編集するデータの取得

id=1のデータを取得する時は、このように書く。

$memo = Memo::find(1);

whereメソッドでも、取得することができる。ただ、whereメソッドは、findメソッドと異なって、条件に合うものを全て取ってくるため、たとえ条件に合うものが一つであったとしても配列として取得するので注意。なのでfirstメソッドで、要素として取得する必要がある。

$memo = Memo::where('id', 1)->first();

データの編集

updateメソッドで、データベース上のデータを書き換えることができる。

$memo->update([
    'title' => $title,
    'content' => $content
]);

MemoControllerを以下のように編集する。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit($id = 0)
    {
        if ($id != 0) {
            $memo = Memo::where('id', $id)->get()->first();
        } else {
            $memo = (object) ["id" => 0, "title" => "", "content" => ""];
        }
        return view("submit", ['memo' => $memo]);
    }

    public function postSubmit(Request $request, $id = 0)
    {
        $title = $request->input('title');
        $content = $request->input('content');
        if ($id == 0) {
            Memo::create([
                'title' => $title,
                'content' => $content
            ]);
        } else {
            $memo = Memo::find($id);
            $memo->update([
                'title' => $title,
                'content' => $content
            ]);
        }
        return redirect()->route('home');
    }
}

データの削除

メモを削除する関数の作成

destroyメソッドを使うと、引数に指定したidのデータだけが削除される。下のコードをMemoControllerに追加する。

public function deleteMemo($id)
{
    Memo::destroy($id);
    return redirect()->route('home');
}

web.phpにdeleteMemoメソッドの登録

/delete/{id}というURLを受け取ったら、メモが削除されるようにする。下のコードをweb.phpに追加する。

Route::get('/delete/{id}', 'MemoController@deleteMemo')->name('delete');

削除ボタンを押したら削除されるようにする

resources/views/home.blade.phpの削除ボタンを以下のように修正する。

<td><a href="{{ route('delete', ['id' => $memo->id])}}">削除</a></td>

おまけ

モーダルを使って、削除の確認をする

bootstrap4のモーダルを使用する。
https://getbootstrap.com/docs/4.3/components/modal/

resources/views/home.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        color: white;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .card {
        margin-top: 40px;
    }

    .left {
        width: 70%;
    }

    .submit {
        position: absolute;
        top: 10px;
        right: 20px;
    }
</style>
@endsection

@section('content')
<div class="card" style="width: 100%;">
    <div class="card-header">
        メモ一覧
        <a href="{{ route('submit')}}" class="submit">メモを追加</a>
    </div>

    <table class="table">
        <tbody>
            @foreach ($memos as $memo)
            <tr>
                <td class="left">{{$memo->title}}</td>
                <td><a href="{{ route('submit', ['id' => $memo->id])}}">編集</a></td>
                <td><a type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">削除</a></td>
            </tr>
            <!-- Modal -->
            <div class="modal fade" id="modal{{$memo->id}}" tabindex="-1" role="dialog" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">以下のメモを本当に削除しますか?</h5>
                            <button type="button" class="close" data-dismiss="modal">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            {{$memo->title}}
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
                            <button type="button" class="btn btn-primary"
                                onclick="location.href='{{ route('delete', ['id' => $memo->id])}}'">
                                削除
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

submitページのボタンを新規作成の時と編集の時で変える

新規作成の時は$memo->id == 0で、編集の時は$memo->id != 0なので、if文で条件分岐する。
resources/views/submit.blade.phpの追加ボタンを以下のように書き換える。

@if($memo->id == 0)
<button type="submit" class="btn btn-success">追加</button>
@else
<button type="submit" class="btn btn-success">適用</button>
@endif

テーブルの列をクリックしたら、詳細画面に飛べるようにする

下のコードを、app.blade.phpのbodyタグの一番下に追加する。

resources/views/layouts/app.blade.php
<script>
    jQuery(function($) {
                $('tbody tr[data-href]').addClass('clickable').click(function() {
                    window.location = $(this).attr('data-href');
                }).find('a').hover(function() {
                    $(this).parents('tr').unbind('click');
                }, function() {
                    $(this).parents('tr').click( function() {
                        window.location = $(this).attr('data-href');
                    });
                });
            });
</script>

home.blade.phpの編集ボタンを消して、trタグにdata-href属性を追加する。

resources/views/home.blade.php
<tr data-href="{{route('submit', ['id' => $memo->id])}}">
       <td class="left">{{$memo->title}}</td>
       <td><a type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">削除</a></td>
</tr>

テーブルの列をホバーすると色が変わるようにする

trタグにclass="table-row"を追加する。

resources/views/home.blade.php
<tr data-href="{{route('submit', ['id' => $memo->id])}}" class="table-row">
       <td class="left">{{$memo->title}}</td>
       <td><a type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">削除</a></td>
</tr>
resources/views/home.blade.php
.table-row {
    background-color: #fff;
}

.table-row:hover {
    background-color: #ddd;
}

追加ボタンをいい感じにする。ヘッダーも固定する。

app.blade.phpでFont Awesomeを読み込む。

resources/views/layouts/app.blade.php
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">

app.blade.phpを以下のように編集する。

resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>MemoApp</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css"
        integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" crossorigin="anonymous">
    <link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous">
    </script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/js/bootstrap.min.js"
        integrity="sha384-3qaqj0lc6sV/qpzrc1N5DC6i1VRn/HyX4qdPaiEFbn54VjQBEU341pvjz7Dv3n6P" crossorigin="anonymous">
    </script>
</head>

<style>
    header {
        background-color: #000;
        background-position: 0px 50px;
        padding-left: 20px;
        font-size: large;
        width: 100%;
        height: 50px;
        clear: both;
        position: fixed;
        top: 0;
        margin-top: 0px;
        z-index: 1;
    }

    .title {
        position: absolute;
        top: 10px;
        color: #fff;
    }

    .container {
        margin-top: 70px;
    }
</style>

@yield('css')

<body>
    <header>
        <span class="title">MemoApp</span>
    </header>

    <div class="container">
        @yield('content')
    </div>

    <script>
        jQuery(function($) {
                $('tbody tr[data-href]').addClass('clickable').click(function() {
                    window.location = $(this).attr('data-href');
                }).find('a').hover(function() {
                    $(this).parents('tr').unbind('click');
                }, function() {
                    $(this).parents('tr').click( function() {
                        window.location = $(this).attr('data-href');
                    });
                });
            });
    </script>
</body>

</html>

home.blade.phpを以下のように編集する。

resources/views/home.blade.php
@extends('layouts.app')

@section('css')
<style>
    .table-row {
        background-color: #fff;
    }

    .table-row:hover {
        background-color: #ddd;
    }

    .card {
        margin-top: 40px;
    }

    .circle-button {
        position: fixed;
        display: inline-block;
        text-decoration: none;
        color: rgba(152, 152, 152, 0.43);
        width: 80px;
        height: 80px;
        line-height: 80px;
        font-size: 40px;
        border-radius: 50%;
        text-align: center;
        overflow: hidden;
        font-weight: bold;
        background-image: linear-gradient(#e8e8e8 0%, #d6d6d6 100%);
        text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.66);
        box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5), 0 2px 2px rgba(0, 0, 0, 0.19);
        border-bottom: solid 2px #b5b5b5;
    }

    .circle-button i {
        line-height: 80px;
    }

    .circle-button:active {
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 2px rgba(0, 0, 0, 0.19);
        border-bottom: none;
    }

    @media screen and (min-width:0px) {
        .circle-button {
            bottom: 20px;
            right: 30px;
        }
    }

    @media screen and (min-width:768px) and (max-width:1024px) {
        .circle-button {
            bottom: 20px;
            right: 50px;
        }
    }

    @media screen and (min-width:1024px) {
        .circle-button {
            bottom: 30px;
            right: 150px;
        }
    }

    .delete-button {
        display: inline-block;
        text-decoration: none;
        width: 20px;
        height: 20px;
        line-height: 20px;
        font-size: 7px;
        border-radius: 50%;
        text-align: center;
        overflow: hidden;
        background-color: #cd5c5c;
        margin-right: 10px;
        margin-top: 5px;
    }

    .delete-button i {
        line-height: 20px;
        color: #fff;
    }

    .td-left {
        width: 10px;
    }
</style>
@endsection

@section('content')
<div class="card" style="width: 100%;">
    <div class="card-header">
        メモ一覧
    </div>

    <table class="table">
        <tbody>
            @foreach ($memos as $memo)
            <tr data-href="{{route('submit', ['id' => $memo->id])}}" class="table-row">
                <td class="td-left">
                    <a class="delete-button" type="button" data-toggle="modal" data-target="#modal{{$memo->id}}">
                        <i class="fa fa-minus"></i>
                    </a>
                </td>
                <td class="td-right">
                    {{$memo->title}}
                </td>
            </tr>
            <!-- Modal -->
            <div class="modal fade" id="modal{{$memo->id}}" tabindex="-1" role="dialog" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">以下のメモを本当に削除しますか?</h5>
                            <button type="button" class="close" data-dismiss="modal">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            {{$memo->title}}
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button>
                            <button type="button" class="btn btn-primary"
                                onclick="location.href='{{ route('delete', ['id' => $memo->id])}}'">
                                削除
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            @endforeach
        </tbody>
    </table>
</div>

<a href="{{route('submit')}}" class="circle-button">
    <i class="fa fa-plus"></i>
</a>

@endsection

submit.blade.phpのcss部分を消しておく。

resources/views/submit.blade.php
@extends('layouts.app')

@section('content')
<form method="POST" action="{{ route('submit', ['id' => $memo->id])}}">
    @csrf
    <div class="form-group">
        <label for="title">タイトル</label>
        <input type="text" class="form-control" id="title" name="title" value="{{$memo->title}}">
    </div>
    <div class="form-group">
        <label for="content">内容</label>
        <input type="text" class="form-control" id="content" name="content" value="{{$memo->content}}">
    </div>
    <a href="{{ route('home')}}" class="btn btn-primary">戻る</a>
    @if($memo->id == 0)
    <button type="submit" class="btn btn-success">追加</button>
    @else
    <button type="submit" class="btn btn-success">適用</button>
    @endif
</form>
@endsection

スクリーンショット 2020-01-04 23.29.44.png

今回はここまで。次回は、ログイン機能を実装します。

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

Laravel で Stripe を使っている人! key は .env に書こう

はじめに

「Laravel Stripe 実装」とかで検索すると、コントローラーに Key を直接書いて動かしている方が多い気がします。(自分もそうしてました...!!)

コントローラーに直接書いても動くのですが、デプロイとかで本番の Key に変換する時にいちいち command + shift + F とかで探すのも面倒ですし、ミスも出やすいし、手間なので、こういう本番環境で変えるだろう設定周りは .env に移動した方が良いと思いました。

.env ファイルに7行追加

# テスト環境
STRIPE_PUBLIC_KEY=pk_test_************************
STRIPE_SECRET_KEY=sk_test_************************

# 本番環境
# STRIPE_PUBLIC_KEY=pk_live_************************
# STRIPE_SECRET_KEY=sk_live_************************

本番環境の時は、テスト環境の2つの key を # でコメントして、本番環境の2つの key の # を取ってあげましょう。

config フォルダに stripe.php ファイルを新しく作成

config/stripe.php
<?php

return [
    'pk_key' => env('STRIPE_PUBLIC_KEY'),
    'sk_key' => env('STRIPE_SECRET_KEY'),
];

Stripe を使っているコントローラーで呼び出し

app/Http/Controllers/StripeControlller.php
// public key (view 側に決済機能を表示させる時に必要)
$stripe_pk_key = config('stripe.pk_key');
dd(stripe_pk_key);

// secret key (支払いが発生した時の決済時に必要)
$stripe_sk_key = config('stripe.sk_key');
dd(stripe_pk_key);

さいごに

自分も、一回一回デプロイする時に、時間かかるし、めんどくさかったし、怖かったので、同じ思いをしている方のお役に立てれば幸いです。

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

Laravel で Stripe を使うなら key は .env に書く

はじめに

「Laravel Stripe 実装」とかで検索すると、コントローラーに Key を直接書いて動かしている方が多い気がします。(自分もそうしてました...!!)

コントローラーに直接書いても動くのですが、デプロイとかで本番の Key に変換する時にいちいち command + shift + F とかで探すのも面倒ですし、ミスも出やすいし、手間なので、こういう本番環境で変えるだろう設定周りは .env に移動した方が良いと思いました。

.env ファイルに7行追加

# テスト環境
STRIPE_PUBLIC_KEY=pk_test_************************
STRIPE_SECRET_KEY=sk_test_************************

# 本番環境
# STRIPE_PUBLIC_KEY=pk_live_************************
# STRIPE_SECRET_KEY=sk_live_************************

本番環境の時は、テスト環境の2つの key を # でコメントして、本番環境の2つの key の # を取ってあげましょう。

config フォルダに stripe.php ファイルを新しく作成

config/stripe.php
<?php

return [
    'pk_key' => env('STRIPE_PUBLIC_KEY'),
    'sk_key' => env('STRIPE_SECRET_KEY'),
];

Stripe を使っているコントローラーで呼び出し

app/Http/Controllers/StripeControlller.php
// public key (view 側に決済機能を表示させる時に必要)
$stripe_pk_key = config('stripe.pk_key');
dd(stripe_pk_key);

// secret key (支払いが発生した時の決済時に必要)
$stripe_sk_key = config('stripe.sk_key');
dd(stripe_pk_key);

さいごに

自分も、一回一回デプロイする時に、時間かかるし、めんどくさかったし、怖かったので、同じ思いをしている方のお役に立てれば幸いです。

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

vagrant homestead.yamlでマウントエラー

vagrantのlaravel/homesteadで開発環境を練習しようとしていますが、現在エラーがでています。
解決方法がわからないので、ご教授お願い致します。

エラーはvagrant upした時に
homestead: Unable to mount one of your folders. Please check your folders in Homestead.yaml
のエラーがでます。
homestead.yamlは
ip: "192.168.80.10"
memory: 2048
cpus: 2
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
- ~/.ssh/id_rsa

folders:
- map: ~/code/Laravel
to: /home/vagrant/code/Laravel

sites:
- map: homestead.app
to: /home/vagrant/code/Laravel/public

databases:
- homestead

features:

です。
pcはmacです。
何か解決方法ございましたら、ご教授お願いします。

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