TravisCI GithubのPush しても’Could not parse’テストが開始しない件

Travis CIを利用しています。
TravisCIの詳しい説明は省略しますが、今回はGithubからPushした際に自動でテスト実行できる環境を構築していきます。

今回、直面した問題はGithubでPushしてもTravisCIが実行されなかった件です。
何度か、Pushしてテストが実行されていたのですが、急に反応しなくなりました。

まず、確認したのは、more option > request

travis_more_option

したのすると、”Could not parse” となりエラーの状態になっていました。

色々と調べていくと、同じようにエラーになっている人がいました。

https://stackoverflow.com/questions/50551277/could-not-parse-travis-yml

ここで紹介されていたのは、.travis.ymlの書き方でのエラーとのことです。
で、下記の便利ツールが紹介されていました。
Pushする前に、.travis.ymlにエラーがないかを判定してくれるツールです。

ここで実行すると、エラーに該当する部分を指摘してくれます。
是非、確認してみてください。

おそらく、インデントや、タブ、スペースなどでエラーになっていることが多いのではないでしょうか。

.travis.yml のcould not parse エラー部分を発見するツール

こちらがエラー判定の便利ツール

http://www.yamllint.com/

heroku CLIをpowershellで起動 Windows編

Docker での開発環境構築は、windowsよりも、macの方がやりやすいのでしょうか。

Dockerを使い始めています。
ひとまず、デプロイ先として、herokuを使おうとして進めていました。

The Heroku CLIをwindowsにてインストールして、windows、powershellにて、herokuを起動させようとしました。

heroku CLIのインストール先
https://devcenter.heroku.com/articles/heroku-cli

インストール自体は、シンプルです。
インストール完了後に、
powershellで、

heroku --version

をしたところ、コマンドレット XXXXXXXXXXXXXXX
herokuがコマンドが無い状態でした。。。

試しに、コマンドプロンプトを開いて、

heroku --version
heroku/7.43.0 win32-x64 node-v12.16.2

heroku CLIをpowershellで起動させるためしたこと

powershellを一度閉じて、再度起動して、heroku –version をするとちゃんと、コマンドが反応しました!!!

これでも、20分くらい彷徨ったので、誰かのために残しておきます。

Laravelで画像をUploadして、表示させる方法

Laravelで画像をUPLOADして、表示させる方法を紹介します。
今回は、POSTで画像をUploadしていきます。
・画像のUpload方法
・画像の表示方法
を紹介していきます。

画像をUploadするための流れを解説

・formを利用して、画像をUpload
・UploadするファイルのPathをデータベースへ保存

formを利用して、画像をUpload

まずは、formを利用して画像をUploadします。
formで、Uploadされた画像は、storageの配下にUPされます。

View____________________

<form method="POST" action="/imageUpload" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="file" id="file" name="profile" class="form">
<button type="submit">アップロード</button>
</form> 

ポイント;
・input type=”file”
・enctype=”multipart/form-data

ファイルアップロードをする場合input要素はを使い、その親のform要素には以下のようにenctype=”multipart/form-data”と書く必要があります。

ROUTE____________________

Route::post('/imageUpload', 'mypageContactController@imageUpload') 

ポイント;
・formのactionが、postで指定するアクション内容となる。

UploadするファイルのPathをデータベースへ保存

Uploadされた画像を呼び出すために、Uploadする画像のPath名称を設定して、そのPathをデータベースに登録する必要があります。

$file_name = time() . '.' . request()->file->getClientOriginalName();
// fileの名称を決定します。
// Uniqueになっていることが重要なので、time()を接頭に追記

$request->file('file')->storeAs('public',$file_name);
// storageは以下のpublicディレクションに、 $file_name で保存



//ここからは、データベースにファイルがUpされているPathを保存
$imagepath = '/storage/' . $file_name;


$loginId = Auth::id();
$profileInfo = User::find($loginId);
//Modelを活用

$profileInfo->imagepath = $imagepath;
// imagepathをデータベースへ保存
$profileInfo->save();

return redirect()->action(
'mypageContactController@profile'
); 

パス名が public/xxxxxxxxxx.jpg となるので不要な public/ の部分を削除しています。

画像を表示するための流れを解説

・シンボリックリンクの作成
・<img src=”path名称”>に、pathを代入する

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

Laravelは、publicディレクトリ配下に存在するファイルしか、表示することができません。しかし、アップロードしたファイルは/storage/appの下にあるためアクセスすることができません。
/publicディレクトリと/storage/appディレクトリとの間でリンクを持たせる必要があります。
それを実行してくれるのが、シンボリックリンクです。

やり方は、いたってシンプルです。
コマンドで下記を実行してください。

 $ php artisan storage:link 

画像を表示させる<img src=”path名称”>に、pathを代入する

あとは、画像を表示させたい場所で、保存したPathを呼び出してあげればよいです。上記で、App\Model\User {{ imagepath }} のカラムへ、Pathをデータベースへ保存しました。

Viewで下記を呼び出してあげればOKです。
※ただし、Viewで呼び出すために、Controllerから、profileInfo(Userのデータ)をView側へcompactで送ってあげることが前提です。

@if(isset( $profileInfo->imagepath ))
<img src="{{$profileInfo->imagepath}}">     
@else
@endif   

LaravelでSNS認証の後に、自動ログイン出来なかった問題を解決。※Guard利用者

LaravelでSNS認証の後に、自動ログイン出来なかった問題がありました。
事象としては、
・Laravelで Socialite を利用して、Twitter認証を作成
・初認証時は、登録→自動ログインの流れ
・データベースには、ユーザー情報は登録されているが、ログイン出来ず。

問題は、Guardを反映することが出来ていなかったことです。

サイトの作りとして、ログイン時に Auth::guard(‘company’)の認証を持つ作りになっていました。

今回の自動ログインでは、Auth:;login()を使っていました。

Auth::login($myinfo);
//$myinfoはユーザー情報

しかし、これでは、自動ログインすることが出来なかったのです。
認証を与えてあげていなかったのが原因です。
認証を与えて → ログインをさせてあげればよいです。
下記書き方で、自動ログインすることが出来ました。

Auth::guard('company')->login($myinfo);

この辺の記述は、 readouble にも記述されていましたので、参考にしてみてください。

https://readouble.com/laravel/5.7/ja/authentication.html

Twitter APIで、TwitterのEmailを取得。getEmail()が機能しなかった忘備録

LaravelでTwitterログイン機能を設定しようとしています。
LaravelでのSNS認証は、ライブラリの Socialite を使うのがオススメです。

今回は、Laravelでのコード内容ではなくて、Twitterに登録しているemailアドレスを取得するためのTwitter Developer上での設定方法を紹介します。

なぜ、この記事を書こうかと思ったかというと
下記のようにemailをTwitterアカウントから取得しようとしたのですが、$emailがnullで取得できなかったためです。

$user = Socialite::with("twitter")->user(); 
$email =  $user->getEmail();

問題は、Twitter Developer上の設定でした。

Authentication settingsで
Request email address from users is enabled に変更します。

こちらの設定をすることで、

$user = Socialite::with("twitter")->user(); 
$email = $user->getEmail();

$emailが取得することが出来ました。

Twitter API でCallback URLsを設定する方法

TwitterでAPI連携する場合には、Twitter Developerに登録する必要があります。そこで、API keyやアクセストークンなどを取得して、各自のアプリケーションにて設定します。

Keyとは別に、callback urlsを必要するもまります。
Callback URLsがどのように使われるのかについては、Oauth 2.0の仕組を解説している方がいらっしゃったので、割愛します。

OAuth 2.0 の認可レスポンスとリダイレクトに関する説明

今回は、 Twitter Developer でCallback URLsを設定する場所を紹介します。

APPを作る際に、もしかしたら設定する箇所があったのかもしれませんが、APP作成後で追加することが可能です。

Developer Portal > Project > App > Appのsetting > Authentication settings

ここから、Editで、Callback URLsを追加することが可能です。

APPを作る際に、もしかしたら設定する箇所があったのかもしれませんが、作成後でもここから追加することが可能です。

Laravelでパスワードを、特定条件の文字列でハッシュ化する方法

Laravelでハッシュ化する際は、
ファザードで Hash::make(password);
を使うことが大半かと思います。

通常の使い方であればこれでいいと思います。
しかし、このhash方法だと、「\」「$」などの記号も含んだ値が返答されます。

そういった文字列は、都合が悪い場合があります。

その際に、一定の条件に従った文字列を返答してくれるハッシュ方法を紹介します。

MD5方式で、16進数・32文字のハッシュ値を生成する
数字とアルファベットも文字列を含んだ値のみを返します。

使い方はいたって簡単です。

md5(password);

することで、レスポンスされます。

まとめて紹介してくれている記事がありましたので、添付します。

Laravel Routeにnameを設定・使い方

Laravelでrouteを利用して、viewを呼び出す際に、Routeにnameを設定する方法を紹介します。

routes\web.php(Routeを設定しているファイル)で、nameを設定します。

 Route::get('/profile', 'mypageController@profile')->name('profile');

記載方法はRouteの最後に、
->name(route名称)でrouteの名称を設定することが出来ます。

nameを設定するメリットについては、Qiitaで分かりやすく解説している方がいたので、ご確認下さい。
Laravel使うならrouteには名前をつけたほうが良い

もう少し使い方について解説します。
Routeでのname設定は、名称を設定しただけです。
これを実際にnameを呼び出して使う方法を紹介します。

routeを使うときは、view bladeの中から呼び出します。

例えば、href にて、リンク先を/profileに設定したい際には、
先ほど、設定したnameを呼び出すカタチで下記のようにリンクに設定します。

<a class="nav-link" href="{{ route('profile') }}">Profile</a>

で、この例だと、ただ、リンクに飛ばしているだけじゃないか、と思うかもしれません。

ここで実験して欲しいのですが

Route:

 Route::get('/profile', 'mypageController@profile')->name('profile.gogogo');

View:

<a class="nav-link" href="{{ route('profile.gogogo ') }}">Profile</a>

と設定しても、/profileへリンクされるのです。
nameはただRouteを接続してくれているだけです。
Routeに設定してある、/profileへの接続は変わりません。

もう一点、私が少し混乱したことについて追記します。
Route設定で、group設定を使う人も多くいると思います。

例えば、下記のようにRoute設定した場合

Route::name('admin.')->group(function () {
   Route::get('/profile', 'mypageController@profile')->name('profile'); 
});

Viewでname を使って、Routeを呼び出す方法は

<a class="nav-link" href="{{ route(' admin.profile') }}">Profile</a>

group 化のname設定によって、nameがadmin.XXXXと設定する必要が出てきます。

Laravelのデータベースリレーションを活用して、別のModelのデータを取得する

Laravelのリレーションを活用することで、リレーション先の異なるテーブルとのデータ連携が可能になります。
非常に重要な機能ですので、是非試してみてください。

今回はリレーションについて2点お伝えしていきたいと思います。

( 1 ):Model内でのリレーションの設定方法
( 2 ):Eloquent で、リレーションを活用して別テーブルのデータを取得する方法

つまり、設定 → データ取得する 一連の流れをお伝えしたいと思います。

( 1 ):Model内でのLaravelリレーションの設定方法

こちらは下記サイトの「Eloquent:リレーション」を一度確認してみてください。

リレーションの方法は幾つかあります。
一番使う形式は、下記3つかと思います。基礎的な部分でいうとこの辺を抑えておけば問題ないと思います。

  • 1対1
  • 1対多
  • 多対多

イメージしやすい例は

1対1:
User_id と マイナンバー
※user_id もマイナンバーもどちらもユニークになる存在なので他のデータとの組み合わせは起きません。

1対多:
User_id と コメント履歴
※AさんのコメントはAさんにしか紐づきません。ただし、Aさんは複数コメントする場合はあります。

多 対 多 :
User_id と 好きな飲食店
※Aさんは、飲食店1、2,3が好き、Bさんは、飲食店2、3,5が好き。というように、紐づきが両データに紐づく可能性があります。

設定方法は、Model内にリレーションのメソッドを記述します。
詳細は 「Eloquent:リレーション」 こちらに書いてある通りです。
1つ注意して確認してみて欲しいのは、
データリレーションには、主従の関係性があるということです。

( 2 ):Eloquent で、リレーションを活用して別テーブルのデータを取得する方法

リレーションを設定する目的の1つは、データを取得しやすくすることです。
簡単な例で紹介します。


A // リレーション設定
※ChatRoomUser クラスから、UserクラスへID同士を紐づけしております。

 <?php

namespace App\Models\Chat;

use Illuminate\Database\Eloquent\Model;

class ChatRoomUser extends Model
{

    protected $fillable = ['chat_room_id', 'user_id', 'usertype'];    

    public function InterviewUser()
    {
        return $this->belongsTo('App\Models\User' , 'user_id' ,'id');
    }
} 

B // リレーションデータの取得
これを設定したことによって、Eloquent でChatRoomUser クラスを活用して、Userクラスの情報を取得できます。

$messageUser = ChatRoomUser::whereIn('chat_room_id', $chat_room_id)
->where('usertype', 'Interviewer')
->get();

foreach($messageUser as $user){
$email = $user->InterviewUser->email;
}
 
 

リレーションを活用した取得方法は下記です。
Eloquantで取得データ- > リレーション設定のメソッド -> リレーションした先のModelのデータカラム

今回でいうと:
・ Eloquantで取得データ  $messageUser
・ リレーション設定のメソッド  InterviewUser
・ リレーションした先のModelのデータカラム  email※Userクラスのデータカラム

リレーションデータ取得時の注意

1件のデータに対してメソッドを適用することが出来る

$messageUser は、配列の中に複数のデータが含まれている場合があります。
配列に対して、 リレーション設定のメソッド をアクセスすることは出来ません。
データを一つづつに分解して、そのデータに対してリレーションメソッドを適用しましょう。

LaravelのFacad/Validator で、ユニーク化するテーブルを変更する方法

Laravel初心者の気づきをお伝えします。

マルチ認証の登録・ログイン方法を試していました。
主に参考にしていたのは、下記のやり方です。

https://qiita.com/namizatop/items/5d56d96d4c255a0e3a87

1つ不都合なことがありました。
Adminで新規登録時に、emailがユニークになるデータベーステーブルの対象先がuserのテーブルだったのです。つまり、Adminで登録しようとした際に、Adminでユニーク判定されるのではなくて、userでユニーク判定されてしまっていました。

原因が分からず、Facad の Validatorにデータベーステーブルを指定する場所があるのかなと思い
Illuminate\Support\Facades\Validator::class,
を調べてみても、テーブルを指定しているようにも見えません。

他を調べてみたところ、
下記がテーブルを指定している場所でした…

return Validator::make($data, [
            'name'     => ['required', 'string', 'max:255'],
            'email'    => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);

ここの部分

'email' => 'unique:users'

app/Http/Controllers/Admin/Auth/RegisterController.php

のuser → adminに変更してあげれば、ユニーク化する対象のテーブルがadminへ変更なります。

return Validator::make($data, [
            'name'     => ['required', 'string', 'max:255'],
            'email'    => ['required', 'string', 'email', 'max:255', 'unique:admin'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);