20210116のlaravelに関する記事は5件です。

RubyOnRails、Authentication plugin 'caching_sha2_password' cannot be loadedエラーの解決法

RubyOnRails、Authentication plugin 'caching_sha2_password' cannot be loadedエラーの解決法

Ruby on rails 開発時に、databaseをmysql 8.0に設定してしたく、database.ymlをmysql設定の上で、rails db:migrate を実行したところ、エラー「Authentication plugin ‘caching_sha2_password’ cannot be loaded」となった時の解決法を共有します。
*laravelにも同様のエラーが発生するとの。

環境の整理

  • 開発環境:Windows10 Home 64ビットオペレーティングシステム、x64ベースプロセッサ
  • Rails version 5系
  • Mysql
    • version 8.0
    • user: root
    • password: root(=今回の例)
  • RubyOnRailsのdatabase.yml設定状況 スクリーンショット 2021-01-16 213315.png

原因

mysql 8.0以降に、認証方式がcaching_sha2_passwordを使うようになったこと。
しかし、Railsはこれに対応していなかったこと。

方法

対象のユーザーの認証方式を「caching_sha2_password」から「mysql_native_password」に変更する。
今回をuserがrootの認証方式を変更する。

  1. mysql -u root -p でmysqlにアクセスする
  2. root (今回のpassword)を入力、Enterする。
  3. SELECT user, host, plugin FROM mysql.user; でユーザー一覧を表示させ、確認する。

    • root の認証方式が「caching_sha2_password」だ 111.png
  4. ALTER USER root IDENTIFIED WITH mysql_native_password BY 'root'; を実行する。

    • 構文:ALTER USER ユーザー名 IDENTIFIED WITH mysql_native_password BY 'password';
  5. SELECT user, host, plugin FROM mysql.user; でrootの認証方式が変更されていることを確認する。
    222.png

  6. exit でmysqlから抜ける

  7. rails db:migrate で本題のrailsのmigrateコマンドを実行する。

  8. エラーなく完了された。
    333.png

*補足:
my.ini(macだとmy.cnf)にて、
default_authentication_plugin=caching_sha2_password

default_authentication_plugin=mysql_native_password
に変更すると、エラーが消えるとの話もあったが、
変更したあとでmysqlを再起動しても変更されなかった。
ちなみに、my.iniの場所は「C:\ProgramData\MySQL\MySQL Server 8.0」である。

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

laravel welcome.blade.phpから他のページに遷移する方法

投稿者の環境

  1. MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)
  2. macOS Big Sur バージョン11.0.1
  3. PHP 7.3.23
  4. Laravel Framework 6.20.7

はじめに

  1. laravelをインストール済みであることが前提となります。
  2. MVCの流れをアウトプットしやすいようにルーティング コントローラー ビューの順に説明します。
  3. 今回は遷移すると文字が表示されるまでとなります。

ステップ1 welcome.blade.phpを編集しよう

laravelをインストール&ローカルサーバーを立ち上げたら大文字でlaravelという大きな文字が出てくると思います。
こちらのページからルーティングを設定しましょう。

welcome.blade.php
<div class="クラス名">
  <a href="{{ url('/about_me/index') }}">about</a>
</div>

//{{ url('/表示させたいフォルダ名/ファイル名') }}

“スクリーンショット” 2021-01-16 15.05.58.jpg
divクラスの入子に<a href="{{ url('') }}">を作成します。
これを設定することによりルーティング化したページに飛べるようになります。
スクショとcssは分かりやすくするために調整しています。

ステップ2 web.phpでルーティングを設定しよう

web.php
Route::get('/about_me/index', 'AboutMeController@index')->name('about_me.index');

// '/about_me/index' 検索窓をクリックしたらURLに表示される部分
/* 'AboutMeController@index' 
@ は、名前空間に属したクラスのメソッド指定の区切り。
名前空間@メソッド名 単刀直入に説明すると 
コントローラー名@viewフォルダにあるファイル名
*/
//  ->name('about_me.index'); 
nameを付けることによりルーティングに名前をつけて尚且つ分かりやすくするため

“スクリーンショット” 2021-01-16 16.06.01.jpg

補足

vscode上にて⌘+pを実行すると指定のファイル名を検索できます!!
ファイル名を探すのが難しかったら是非覚えてください!!
“スクリーンショット” 2021-01-16 15.18.39.jpg

ステップ3 コントローラーを作成しよう

//ターミナルにて
php artisan make:controller AboutMeController 

//命名規則 php artisan make:controller 付けたい名前+controller
/* 補足 
php artisan make:controller Testcontroller --resource
これを実行すると index create store等々の全てのコントローラーが作成される
*/

ステップ4 作成したコントローラーを編集しよう

AboutMeController.blade.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AboutMeController extends Controller
{
    public function index()
    {
        //表示させたいviewを指定させる
        return view('about_me.index');
    }
}

ステップ5 viewファイルを作成しよう

viewファルを作成するには手動にて作成します。
これからviewファイルを沢山作成する可能性がある場合はフォルダ毎に分けるのが一番分かりやすいです!!
フォルダ名/ファイル名

ステップ6 viewファイルに文字を入れよう

about_meフォルダ/index.blade.php
<!DOCTYPE HTML>
<html>
<head>
    <title>About</title>
</head>
<body>
    <h1>About Me</h1>
</body>
</html>
<h1>about_meフォルダのindexファイル</h1>

ステップ7 ページが遷移されるか確認しよう

ページが遷移されるかを確認するためローカルサーバーを立ち上げてください。
もし画面が遷移されない場合は下記を実行して下さい。

  1. 名前に間違いがないか?ちゃんと橋渡しができているかどうか。
  2. 分かりにくい場合はphp artisan route:list > route1.txtを実行。ルーティングの一覧が出てきます。
ターミナルにて
php artisan route:list > route1.txt

以上となります。

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

Docker × Laravel ローカル環境でHTTPS(SSL)通信する

ローカル環境でもHTTPS通信したいという要望があり、ちょうど最近仕事でやる機会があったのでQiitaにもまとめたいと思います。

Laravel環境構築

$ git clone git@github.com:ucan-lab/docker-laravel.git
$ cd docker-laravel
$ make create-project

http://localhost

ScreenShot 2021-01-16 15.24.23.png

認証局、鍵の準備

mkcert, nssのインストール

$ brew install mkcert nss

ローカル認証局(CA: Certification Authority)の作成

$ mkcert -install

ChromeのSSL警告をlocalhostの時だけ表示しないようにする。
chrome://flags/#allow-insecure-localhost アドレスバーに入力する。

ScreenShot 2021-01-16 14.56.07.png

DISABLED => ENABLED に変更してブラウザを再起動する。

秘密鍵、公開鍵の作成

コマンドの実行は docker-laravel ディレクトリルートで行ってください。

$ mkcert -cert-file ./infra/docker/nginx/localhost.pem -key-file ./infra/docker/nginx/localhost-key.pem localhost

Dockerのコード書き換え

docker-compose.yml

公開ポートを80から443へ変更する。
HTTPSは、ウェルノウンポート番号として443が使われるのが一般的です。

docker-compose.yml
services:
  web:
    ports:
      - ${WEB_PORT:-443}:443

infra/docker/nginx/default.conf

下記のコードを追記する。

infra/docker/nginx/default.conf
server {
    # listen 80;
    listen 443 ssl;
    server_name localhost;
    ssl_certificate /etc/nginx/conf.d/localhost.pem;
    ssl_certificate_key /etc/nginx/conf.d/localhost-key.pem;

    # ... 省略
}

infra/docker/nginx/Dockerfile

下記のコードを追記する。

infra/docker/nginx/Dockerfile
COPY ./*.pem /etc/nginx/conf.d/
  • 秘密鍵、公開鍵をコピーしてます。

Dockerイメージの作成、コンテナ再生成

コマンドの実行は docker-laravel ディレクトリルートで行ってください。

$ docker-compose build web
$ make restart

https://localhost

ScreenShot 2021-01-16 14.54.27.png

ScreenShot 2021-01-16 14.54.39.png

このようにSSL証明書が有効化されていればokです。

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

LaraveのhasOneとbelongsToの違い

参照先 or 参照される側 or 外部キーがある側は、belongsTo
参照元 or 参照する側 or 外部キーがない側は、hasOne

UsersMedel.php
[id,name] //だとする
    public function profile()
    {
        return $this->hasOne(Profiles::class, 'user_id', 'id');
    }
ProfilesMedel.php
[id,memo,address,user_id] //だとする
    public function profile()
    {
        return $this->belongsTo(Users::class, 'user_id', 'id');
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】投稿機能をていねいに。

投稿機能を実装

投稿機能のビュー、コントローラー、モデルの実装をしたので自分用にメモ。
作っているアプリ:日本酒のレビュー投稿アプリを作成中

以下3つのファイルを編集しました。
①review.blade.php(ビュー)
②ReviewsController.php(コントローラー)
③Review.php(モデル)

フォーム自体はこちら↓。

image.png
※画像投稿、保存に関しては後日機能を追加する予定なので今回は省きます。

まず最初に!

・HTMLタグのnamevalueはサーバーサイド側で処理を行う上で重要!これがあればOKと言っても過言ではないくらい大事。
→私はinput要素にvalueをつけず、
nameがテーブルのカラムと一致しない値のため修正しました。
カラム;image、html:review_image

ビューの編集

<div class="md-form">
        <label class="wf-mplus1p">日本酒名</label>
        <input type="text" name="title" class="form-control" required value="{{ old('title') }}">
    </div>

    <div class="nihonshu-image pl-5">
        <label class="nihonshu-image  wf-mplus1p">画像</label>
        <input type="file" name="image" accept="image/jpeg, image/png"  class="mx-auto pt-3">
    </div>


    <div class="taste-ev ">
        <label class="taste-evl pl-5 wf-mplus1p">味の濃さ</label>
        <div class="ratebutton text-center">
            <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="taste_intensity" value="1">
                <label for="1">1</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="taste_intensity" value="2">
                <label for="2">2</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="taste_intensity" value="3" checked>
                <label for="3">3</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="taste_intensity" value="4">
                <label for="4">4</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="taste_intensity" value="5">
                <label for="5">5</label>
            </div>
        </div>
    </div>


    <div class="scent-evl">
        <label class="taste-evl pl-5 wf-mplus1p">香りの強さ</label>
        <div class="ratebutton text-center">
                <div class="md-radio md-radio-inline d-inline">
                <input  type="radio" name="scent_strength" value="1" checked>
                <label for="1">1</label>
                </div>
                <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="scent_strength" value="2" checked>
                <label for="2">2</label>
                </div>
                <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="scent_strength" value="3" checked>
                <label for="3">3</label>
                </div>
                <div class="md-radio md-radio-inline d-inline">
                <input type="radio" name="scent_strength" value="4">
                <label for="4">4</label>
                </div>
                <div class="md-radio md-radio-inline d-inline">
                <input  type="radio" name="scent_strength" value="5">
                <label for="5">5</label>
                </div>
        </div>
    </div>


    <div class="comp-evl">
        <label class="taste-evl pl-5 wf-mplus1p">総合評価</label>
        <div class="ratebutton text-center">
            <div class="md-radio md-radio-inline d-inline">
            <input  type="radio" name="evaluation" value="1">
            <label for="1">1</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
            <input type="radio" name="evaluation" value="2">
            <label for="2">2</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
            <input  type="radio" name="evaluation" value="3" checked>
            <label for="3">3</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
            <input type="radio" name="evaluation" value="4">
            <label for="4">4</label>
            </div>
            <div class="md-radio md-radio-inline d-inline">
            <input  type="radio" name="evaluation" value="5">
            <label for="5">5</label>
            </div>
    </div>
    </div>

    <div class="form-group">
        <label></label>
        <textarea name="content" required class="form-control wf-mplus1p" rows="4" placeholder="メモ">{{ old('body') }}</textarea>
    </div>


コントローラー編集

?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Review;

class ReviewsController extends Controller
{

    public function index()
    {
        return view('top.index');
    }


    public function create(Request $request)
    {
        $inputs = $request->all();

        // $inputsが空じゃなかったら実行
        if ( !empty($inputs) ) {
            // ログイン中のユーザーIDを取得
            $current_user_id = Auth::user()->id;

            $value = [
                'user_id'         => $current_user_id,
                'title'           => (string) $inputs['title'] ?? '',
                'content'         => (string) $inputs['content'] ?? '',
                'taste_intensity' => (int) $inputs['taste_intensity'],
                'scent_strength'  => (int) $inputs['scent_strength'],
                'evaluation'      => (int) $inputs['evaluation'],
                'image'           => (string) $inputs['image'],
            ];
            Review::create($value);
        }
        return view('top.index');
    }
}


ポイント

・createメソッドの作成
$request->allで全てを取得
!empty$inputsが空ではない場合に実行するよ、という関数。
 逆はempty
$current_user_idでログインユーザーidを取得
$valueでレコードのカラム型に応じた連装配列を作る
・Reviewモデルに渡す
・投稿し終わったらtop.indexを表示
★ (int)によって型チェックを行う
★ ?? ''を設定してもし絵文字などint型以外の入力があった場合は空白にする

モデル編集

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Carbon\Carbon;

class Review extends Model
{
    protected $table = "reviews";

    // ★idカラムの更新・挿入はさせない
    protected $guarded = ['id'];

    // ★自動でupdated_atとcreated_atをレコード挿入時に入れてくれる
    public $timestamps = true;


    /* ----- リレーション ----- */
    public function user(): BelongsTo
    {     
        return $this->belongsTo('App\User');
    }
}

 ポイント

★ idカラムの更新や挿入ができないようにする
★ 自動でupdated_id,created_atをレコード挿入時に入れる

無事DBにも保存できました〜〜!

スクリーンショット 2021-01-16 0.42.05.png

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