大量のカラムを持つテーブルに対してSQLのINSERT文を生成しなければいけなくなった時の為の備忘録
2022年読んだ書籍まとめ
2022年読んだ書籍は33冊でした。
数としてあまり多くはなかったですが、読んだ本を振り返ってみると、ロシアのウクライナ侵攻があった影響で読んだ本が数冊あるのと、歴史系の本にハマった1年という感じです。
そんな中、1年通して最も読んで良かったと思ったのは「坂の上の雲」でした。
いざ読んでみると、面白くてドンドコ読み進めてしまいました。
前半などは青春小説のようにも読めますし、日本人が無邪気に大志を抱けた時代として描かれている内容に清々しいような気持ちでのめり込んで読み耽りました。
2023年は引き続き歴史系の書籍を読み進めたいのと、技術系の本ももちろん有名どころからどんどん手を出していこうと思います。(2022年は技術系の書籍は少なかったので。。)
以下、2022年に読んだ書籍一覧
ーーーーーーーーーーーーーー
独ソ戦
戦略の地政学
坂の上の雲(1〜6巻)
C言語
居るのはつらいよ
自分を超える心とからだの使い方
瞑想と認知科学の教室
竜馬がゆく(1〜8巻)
新しい地政学
ポートとソケットが分かればインターネットがわかる
アルツハイマー征服
同志少女よ、敵を撃て
それでも映画は格差を描く
アグルーカの行方
夜もまた夜の深い夜
気候危機とグローバル・グリーンニューディール
猿の見る夢
繊細さんの本
エンジニアリンク組織論への招待
リーダブルコード
十字軍物語(1巻)
2022年観た映画ベスト3を勝手に発表
今年入ってから観た映画の中で観て良かった映画を3本選出。
対象はあくまで今年観た映画であって、公開は今年に限らず。
1位 スティルウォーター(2022年公開)
2位 コーダ あいのうた(2022年公開)
3位 スパイダーマン ノーウェイ・ホーム(2021年公開)
という事で1位はアマプラで観れるスティルウォーターでした。
もっさり系マットデイモンが拝める作品ですが、観た感想としては「渋い。。」の一言。
あんまり話題になっていない気がしますが、個人的には大オススメ。
2時間という枠組みで強烈なパンチを食らったような気分になり、余韻に浸りながら反芻してしまいます。
アテナなどと同じくフランスという国が抱えている難しさが表れていて、「あなたはトランプに投票した?」というセリフには思わずニヤリとしてしまうと同時に、なるほどなぁと思ってしまいました。
結果、今年観たのは全部で62本でした。
(連続ドラマは全シーズン合わせて1本と換算。けっこうメモるの忘れてるのもあるので、実際はもうちょい観てるはず)
本当は今年公開の映画だけで選出するべきでしょうが、もうあまり映画を観ない生活になっているので、あくまで今年観た映画という枠。
1話1時間程度で観れるドラマはかなり魅力的で、以前はドラマはほぼ観てなかったが、昨年あたりから映画を観るよりもドラマを観る機会の方が増えたかもしれないです。
そんなドラマの中部門でのベストは
「ベターコールソウル(Netflix)」
シーズン6まで一気見。シーズン4あたりでややダレるが、シーズン1や2の頃からの伏線が最後で一気に回収されます。
終わり方も決して華やかな終わりでないところが非常に渋く大人向けな作品。
ブレイキングバッドのスピンオフ作品だが、ブレイキングバッド観てなくても充分楽しめます。
他にも、今さら最初から観た「ストレンジャーシングス」、「ウ・ヨンウ弁護士」も好きです。
映画では公開がけっこう前ですが「ヴィジット」や「アメリカン・アニマルズ」、「バーバリアン」なども好きでした。
どれもアマプラ、Netflixで観れるので未見の方はぜひ観てみてください。
観た作品リスト↓
グリーンブック
ファーザー
ブラッククランズマン
バイス
ドッグバイトドッグス
ゼアウィルビーブラッド
のび太の大魔鏡
ペンタゴンペーパーズ
続ボラット
ブラックスキャンダル
Time to kill
マンオンファイア
裏切りのサーカス
ワールドオブライズ
シリアナ
インサイドマン
のび太の魔界大魔境
クリード
カジノ
ドゥザライトシング
ケープフィアー
パスオーバー
アメリカンアニマルズ
ヴィジット
太陽の下で
リリーのすべて
さがす
岬の兄弟
狐狼の血2
モアナ
龍とそばかすの姫
コーダ
ウィンストン・チャーチル
ヴェノム レットゼアビーカーネイジ
ジョニーイングリッシュ気休めの報酬
容疑者、ホアキン・フェニックス
OUTER RANGE(Amazon Primeドラマ)
NOPE
ゲットアウト
アス
ドクターストレンジ マルチバース
スパイダーマン ノーウェイホーム
オールド
マイティソー ラブアンドサンダー
スティルウォーター
アテナ
ベターコールソウル Season1~6(Netflixドラマ)
ストレンジャーシングス Season1~4(Netflixドラマ)
モール
ドント・ルックアップ
バーバリアン
シンウルトラマン
犯罪都市
シング2
13人の命
ウ・ヨンウ弁護士は天才肌 (Netflixドラマ)
ファイアオブラブ
クロティルダの子孫たち
おやすみオポチュニティ
ジェントルマン
すずめの戸締り
呪術廻戦0
You have provided an out-of-range value `undefined` for the select component. Consider providing a value that matches one of the available options
Reactの勉強の為、アプリを作成しており、MUIのSelectコンポーネントを使用していたら下記のようなwarning文が出てきました。
MUI: You have provided an out-of-range value `undefined` for the select component. Consider providing a value that matches one of the available options
ググってみたところ、有効な解決策が見つからなかったのですが、上記文を直訳すると
選択コンポーネントに範囲外の値「未定義」を指定しました。 利用可能なオプションのいずれかに一致する値を提供することを検討してください
という内容になります。
該当ソースコードが下記になります。
const [selectedEditCategory, setSelectedEditCategory] = useState(""); consthandleEditRegularTaskOpen= (task) =>{ setSelectedEditCategory(task.category); }; return( <FormControlsx={{ ml:1, minWidth:100}}size="small"> <InputLabelid="demo-simple-select-label">種別</InputLabel> <Select labelId="demo-simple-select-label" id="demo-simple-select" value={selectedEditCategory} label="種別" onChange={handleChangeEditCategory} MenuProps={MenuProps} > {options.map((category, index) =>( <MenuItemkey={index}value={category}>{category}</MenuItem> ))} </Select> </FormControl> )
編集画面でDBから取ってきた値をSelectの初期値として表示させているのですが、DBにnullのデータがあったのが原因で、warning文にあるように「selectの選択肢に未定義はないのに未定義が選択されている」と言うwarning文が発生していたようです。
なので、解決策としてDBの値がnullであれば空文字を表示するようにしたところwarning文が消えました。
修正ソースコード
const [selectedEditCategory, setSelectedEditCategory] = useState(""); consthandleEditRegularTaskOpen= (task) =>{ // 下記を修正 setSelectedEditCategory(task.category || ""); }; return( <FormControlsx={{ ml:1, minWidth:100}}size="small"> <InputLabel id="demo-simple-select-label">種別</InputLabel> <Select labelId="demo-simple-select-label" id="demo-simple-select" value={selectedEditCategory} label="種別" onChange={handleChangeEditCategory} MenuProps={MenuProps} > {options.map((category, index) => ( <MenuItem key={index} value={category}>{category}</MenuItem> ))} </Select> </FormControl> )
結論。
warning文やerror文をちゃんと読むのが解決への道。
react-selectが便利だった件
react勉強中。勉強も兼ねてタスク管理アプリをreactで作成することに。
その中でセレクトボックスを作成したのですが、react-selectでサクッと実装出来ました。
使い方
1. インストール
npm i --save react-select
2. 使用するコンポーネント箇所でimport
import React from 'react'
import Select from 'react-select'
3. セレクトで表示させる選択肢を用意し、Selectコンポーネントのoptionsに渡す。
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
const MyComponent = () => (
<Select options={options} />
)
4. 以上。
めちゃ簡単でした。セレクトする際のアニメーションをつけられたり、選択肢のラベルごとに色をつけられたり、カスタマイズも可能です。
私は複数選択可能にするmultiを使いました。
import React from 'react';
import Select from 'react-select';
import { colourOptions } from '../data';
export default () => (
<Select
defaultValue={[colourOptions[2], colourOptions[3]]} // 初期選択の設定
isMulti // 複数選択可能にする
name="colors"
options={colourOptions} // 選択肢colourOptionsを渡す
/>
);
まとめ
セレクトボックスをサクッと実装できて、公式ドキュメントも非常にわかりやすいので、自作アプリなどでセレクトボックス実装する際は有用だと思います。
参考
https://github.com/jedwatson/react-select
Firebaseに保存したtimestamp型のデータを表示させる
現在作成している自作アプリでFirebaseを利用していて、timestamp型のデータの表示方法を備忘録としてまとめ。
timestamp型のデータをそのまま取得すると下記のようなデータになっている。(startDateというtimestamp型のデータを取得した場合)
console.log(startDate);
// 下記のように表示される
1. まずはtoDate()で日時表記に
const start = startDate.toDate();
console.log(start);
// Mon Sep 19 2022 05:06:18 GMT+0900 (日本標準時)
console.log(typeof(start))
// object
ただし、このままだとobjectなので、そのまま
<div>開始日時:{start}</div>
という風に表示させようとすると
Uncaught Error: Objects are not valid as a React child (found: Mon Sep 19 2022 05:06:18 GMT+0900 (日本標準時)). If you meant to render a collection of children, use an array instead.
というエラー文が表示される。なので、
2. formatを使って文字列にし、任意の形式に成形する
import { format } from 'data-fns'
const formattedStart = format(start, 'yyyy/MM/dd')
console.log(formattedStart);
// 2022/09/19
console.log(typeof(formattedStart));
// string
上記のようにすることで、
<div>開始日時:{formattedStart}</div>
// 開始日時:2022/09/29 と表示される
日付を操作するライブラリとしてdata-fns以外にもdayjs、moment.jsなどがあるらしいが、自分はdata-fnsを使いました。
date-fns - modern JavaScript date utility library
参考サイト
[Firebase]Timestamp()を使って日時を取得、取得した情報を整形する方法[Cloud Firestore] | tedate
TypeError: date.format is not a function in JavaScript | bobbyhadz
マルチログインを実装したLaravelアプリでユーザー登録時に認証メールが送られるようにする
Laravel Breezeではユーザー登録時に認証メールが送られるようにする機能が備わっており、簡単に実装できるようです。
が、現在BtoCのアプリを作成しており、マルチログイン(ユーザー、企業、管理者など、それぞれでログインできる)を実装している関係で、認証メール実装するまでに少し時間がかかりました。
https://qiita.com/may_nkn/items/b396bb211c66ade07adf
主に上記の記事を見ながら実装してみたのですが、記事の通りやってもうまくいかなかった箇所もあったので、追加で行った処理も記載し、備忘録として実装までの道筋をまとめておこうと思います。
- 1. 認証メールが送られるようにMustVerifyEmail追加
- 2. 以下コマンドでVerifyEmail.phpを作成
- 3. User.phpでsendEmailVerificationNotificationをオーバーライド
- 4. app\Http\Middleware\EnsureEmailIsVerified.phpを作成し、vendor\laravel\framework\src\Illuminate\Auth\Middleware\EnsureEmailIsVerifiedの内容をコピー
- 5. kernel.phpの内容を変更
- 6. ルーティングでverifiedを適用
1. 認証メールが送られるようにMustVerifyEmail追加
マルチログインではなく、ただ認証メールが送信されるようにするのは簡単で、
User.phpでUserクラスに対してMustVerifyEmailインターフェースを指定するだけで実現できます。
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
-class User extends Authenticatable
+class User extends Authenticatable implements MustVerifyEmail
{
use HasFactory, Notifiable;
が、マルチログインだと多少コードを修正していく必要があります。
2. 以下コマンドでVerifyEmail.phpを作成
作成されたVerifyEmail.phpに
vendor\laravel\framework\src\Illuminate\Auth\Notifications\VerifyEmail.phpの内容をコピー。
元記事でも説明されてますが、マルチログイン実装している関係でrouteを記載している箇所だけ修正する必要があります。
vendor配下のコードを直接修正するのは良くないので、user配下にVerifyEmailを作成し、そちらを修正する手順をとっています。
app\Notifications\User\VerifyEmail.php
protected function verificationUrl($notifiable)
{
if (static::$createUrlCallback) {
return call_user_func(static::$createUrlCallback, $notifiable);
}return URL::temporarySignedRoute(
- ‘verification.verify’,
+ ‘user.verification.verify’,
Carbon::now()->addMinutes(Config::get(‘auth.verification.expire’, 60)),
[
‘id’ => $notifiable->getKey(),
‘hash’ => sha1($notifiable->getEmailForVerification()),
]
);
}
3. User.phpでsendEmailVerificationNotificationをオーバーライド
app/Models/User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;
+ use App\Notifications\User\VerifyEmail;class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;
use SoftDeletes;+ public function sendEmailVerificationNotification()
+ {
+ $this->notify(new VerifyEmail());
+ }
}
こちらは元は
vendor\laravel\framework\src\Illuminate\Contracts\Auth\MustVerifyEmail.php
の中で定義されているメソッドです。
また、use文で先ほど生成したVerifyEmailを呼び出せるようにしておきます。
ちなみに、上記メソッドは
app\Http\Controllers\Auth\EmailVerificationNotificationController.phpの中で呼ばれていました。
<?php
namespace App\Http\Controllers\User\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;class EmailVerificationNotificationController extends Controller
{
public function store(Request $request)
{
if ($request->user()->hasVerifiedEmail()) {
return redirect()->intended(RouteServiceProvider::HOME);
}$request->user()->sendEmailVerificationNotification();
return back()->with(‘status’, ‘verification-link-sent’);
}
}
4. app\Http\Middleware\EnsureEmailIsVerified.phpを作成し、vendor\laravel\framework\src\Illuminate\Auth\Middleware\EnsureEmailIsVerifiedの内容をコピー
こちらもマルチログインの関係でコードを修正する必要があるのですが、先ほどと同様vendor配下のコードを修正するのは良くないので、app配下のMiddlewareに新規でEnsureEmailsVerified.phpを作成し、そちらコピーしてから修正します。
app\Http\Middleware\EnsureEmailIsVerified.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;class EnsureEmailIsVerified
{
public function handle($request, Closure $next, $redirectToRoute = null)
{
if (
!$request->user() ||
($request->user() instanceof MustVerifyEmail &&
!$request->user()->hasVerifiedEmail())
) {+ if (get_class($request->user()) === ‘App\Models\User’) {
+ $path = ‘user.’;
+ } elseif (get_class($request->user()) === ‘App\Models\Companies’) {
+ $path = ‘company.’;
+ }
return $request->expectsJson()
? abort(403, ‘Your email address is not verified.’)- : Redirect::guest(URL::route($redirectToRoute ?: ‘verification.notice’));
+ : Redirect::guest(URL::route($redirectToRoute ?: $path . ‘verification.notice’));
}return $next($request);
}
}
上記のif文でUserクラスなのかCompaniesクラスなのかで条件分岐してrouteのパスが
'verification.notice' でなく
'user.verification.notice' や 'company.verification.notice' になるようにします。
(もちろん、環境によりrouteのパスは違うと思いますが)
5. kernel.phpの内容を変更
routes配下でルーティングを定義する際に'verified'をmiddlewareとして指定すれば、メール認証済みかどうかをチェックしてくれますが、元の設定ではvendor配下のEnsureEmailsVerifiedが呼ばれてしまうので、上記で生成した方を呼び出すよう
Kernel.phpを修正。
app\Http\Kernel.php
protected $routeMiddleware = [
‘auth’ => \App\Http\Middleware\Authenticate::class,
‘auth.basic’ => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
‘cache.headers’ => \Illuminate\Http\Middleware\SetCacheHeaders::class,
‘can’ => \Illuminate\Auth\Middleware\Authorize::class,
‘guest’ => \App\Http\Middleware\RedirectIfAuthenticated::class,
‘password.confirm’ => \Illuminate\Auth\Middleware\RequirePassword::class,
‘signed’ => \Illuminate\Routing\Middleware\ValidateSignature::class,
‘throttle’ => \Illuminate\Routing\Middleware\ThrottleRequests::class,
- ‘verified’ => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
+ ‘verified’ => \App\Http\Middleware\EnsureEmailIsVerified::class,
6. ルーティングでverifiedを適用
後は任意のルートにmiddlewareで'verified'を指定すれば、メール認証が済みかどうかチェックしてくれるようになります。
routes\web.php
Route::resource(‘user’, UserController::class, [‘except’ => ‘index’])->middleware([‘auth:users’, ‘verified’]);
などと指定すると、上記のルーティング先でメール認証済みかどうかチェックされ、認証済みでないと
resources\views\auth\verify-email.blade.phpが読み込まれ、下記のように表示されます。
間違い等あればご指摘お願いします。