【シリーズ☆エンジニアの筋肉メシ】鶏ささみのトマトときゅうりの中華和え

はじめに

これは「ブロッコリー」「ほうれん草」「鶏ムネ肉」しか食べてはいけない呪いを掛けられたエンジニアの料理の記録である

毎日飽きずに食べ続けられるか、それだけに全振りした超雑記

特に料理の知識も栄養の知識もないので参考にしてはいけない(栄養は他でしっかり補ってます)

今日の一品「鶏ささみのトマトときゅうりの中華和え」

ささみがパサパサで少しでも潤いが欲しかったので、ほとんど水のきゅうりとトマトで和えてみます

こちらを参考にしました

cookpad.com

f:id:cgig:20210111231951j:plain
材料

f:id:cgig:20210111232021j:plain
ささみをボイル

f:id:cgig:20210111232112j:plain
きゅうりを千切り
千切りがうまく出来なくて大きさがバラバラです

f:id:cgig:20210111232203j:plain
トマトはブロックに
想像だけで切ったら、うまくブロックに切れませんでした

切り方勉強します

f:id:cgig:20210111232321j:plain
たれ
例によって適当に混ぜ合わせます

無性に酸っぱい物が食べたいので8割酢です

大さじ小さじが欲しい

f:id:cgig:20210111232410j:plain
混ぜる

全てを皿に投入して、グジュグジュに混ぜ合わせます

f:id:cgig:20210111232532j:plain
盛り付けて完成!

本日の撮れ高

味    :★★★☆☆ (2)
酒に合う度:★★★☆☆ (2)

たぶん手際が良くなくて、水っぽくなってしまった。中華ドレッシング使ってないのに味が中華っぽくなって感動した

【シリーズ☆エンジニアの筋肉メシ】ブロッコリーとえのきの和え物

はじめに

これは「ブロッコリー」「ほうれん草」「鶏ムネ肉」しか食べてはいけない呪いを掛けられたエンジニアの料理の記録である

毎日飽きずに食べ続けられるか、それだけに全振りした超雑記

特に料理の知識も栄養の知識もないので参考にしてはいけない(栄養は他でしっかり補ってます)

今日の一品「ブロッコリーとえのきの和え物」

f:id:cgig:20210110210540j:plain
ブロッコリーとしめじ
下ゆでして冷ましました

f:id:cgig:20210110210710j:plain
適当に見繕った調味料

f:id:cgig:20210110210742j:plain
全部投入
小さじや大さじを持ってないので適当な分量で混ぜ合わせます

f:id:cgig:20210110211115j:plain
具材を入れて混ぜる
グジュグジュに混ぜ合わせます

味が薄かったので塩を足しました

f:id:cgig:20210110205527j:plain
盛り付けて完成!

本日の撮れ高

味    :★★★☆☆
酒に合う度:★★★★☆

ごま油入れすぎて油っぽかったです。物足りないのでゴマなんかあればもっと良かったかも

【サービスリリース】OpenListを公開しました

openlist.cgig.jp

みんなで簡単にタスク管理ができるWebサービスです

コンセプト

調整さんのタスク管理バージョン笑

実際調整さんってすごい優秀で

  • 普段Webサービスを使わない人でも使える(誰でも簡単)
  • めんどうなステップはなく、すぐに調整できる(ログイン不要)

っていう素敵なシンプルさがあると思っています

そんな調整さんみたいなサービスにしたくて開発しました

コンセプトを思いついたのはバーベキューの買い出しの時です

2〜30くらいの食材をリスト化した時に、さくっとグループ共有して、管理できるいい方法が見つからなかったので

そういうサービスがあればいいなと思いました

使い方

使い方は簡単です

まずはカテゴリー、名前を決めてリストを作成します

f:id:cgig:20210111221923p:plain

そしたらあとはよくあるタスク管理ツールのようにタスクを登録していくだけです

f:id:cgig:20210111222106p:plain

同期しているので、他の人のブラウザ上でも更新されます

なので、買い出しをしているときもあと何を買えばいいかが一目でわかります

今後について

機能を付け足していってシンプルさがなくなるとよくないので、バランスをみながら開発していこうと思います

是非ご利用ください

【シリーズ☆エンジニアの筋肉メシ】鶏肉の酒蒸し

はじめに

これは「ブロッコリー」「ほうれん草」「鶏ムネ肉」しか食べてはいけない呪いを掛けられたエンジニアの料理の記録である

毎日飽きずに食べ続けられるか、それだけに全振りした超雑記

特に料理の知識も栄養の知識もないので参考にしてはいけない(栄養は他でしっかり補ってます)

今日の一品「鶏肉の酒蒸し」

f:id:cgig:20210110204333j:plain
最初から切ってある鶏肉
こいつをシバいていきます

今日は酒蒸しに挑戦

f:id:cgig:20210110204516j:plain
使う調味料

f:id:cgig:20210110204905j:plain
適当に油を敷きます
サラダ油がなかったのでオリーブオイルです

f:id:cgig:20210110205004j:plain
適当に味付け
臭みを取りたいのでブラックペッパーを振ってみます

油が温まってなかったので鍋にくっ付いてます

f:id:cgig:20210110205206j:plain
少し焼いたら酒を投入
めんどうなので特に測りません

f:id:cgig:20210110205306j:plain
蒸してるつもり

f:id:cgig:20210110205411j:plain
5分ほど放置して開けたらいい感じ

f:id:cgig:20210110205527j:plain
盛り付けて完成!
多分味が薄いのでポン酢を掛けて食べます

本日の撮れ高

味    :★★★☆☆
酒に合う度:★★☆☆☆

味が薄かったです。ポン酢をかけると何でもうまい!

Prisma2でschemaファイルを分割して管理する

はじめに

最近Prismaを使い始めたんですが schema.prisma が肥大化していって辛くなってきたので分割を考えました

分割方法を調査

調べたところ、同じことを思ってる人はいるようでissueがありました

Prisma1の場合はPrismaがよしなにしてくれたようなのですが、2にはその機能がないみたいなので自前でmergeするみたいです

github.com

そこで紹介されているこちらのパッケージを使ってみます

github.com

分割する

現在 prisma init すると prisma/schema.prisma が生成されるので

prisma フォルダ内で作業します

まず base.schema を作ります

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

base.schema にはdatasourceやgeneratorの設定を入れます

次に models フォルダに各Modelを1ファイルごとに入れていきます

models/User.prisma

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
  posts   Post[]
}

models/Post.prisma

model Post {
  id         Int         @id @default(autoincrement())
  createdAt  DateTime    @default(now())
  title      String
  published  Boolean     @default(false)
  author     User        @relation(fields: [authorId], references: [id])
  authorId   Int
  categories Category[]  @relation(references: [id])
}

VSCodePrismaの拡張をインストールしていると参照エラーが出ますが気にしないでいきます

最後にコマンドを実行します

デフォルトだと src 以下になっているので各パスを指定します

npx prisma-merge --baseFile prisma/base.prisma --schemaFilePatterns 'prisma/*/*.prisma' --outputFile prisma/schema.prisma

このとき --schemaFilePatterns prisma/*/*.prisma のようにクォートで囲まないと展開されてエラーになってしまうので注意

prisma/schema.prisma が生成されていれば成功です

TypeScriptでクラスを初期化するときにObjectを渡して初期化したい

はじめに

下記のようなクラスがあった場合にどうやって初期化しようかと悩んだため色々試してみました

class User {
    name: string;

    age: number;

    nickname?: string;

    public hello(): string {
        return `[${this.nickname ?? this.name}] Hello!!`;
    }
}

やったこと

先に結論ですが、最終的には下記の形に落ち着きました

// Tのpropertyの名前の列挙
type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T];

// Tのproperty
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;

class User {
    name?: string = 'anonymous';

    age!: number;

    nickname?: string;

    public constructor(params: NonFunctionProperties<User>) {
        Object.assign(this, params);
    }

    public hello(): string {
        return `[${this.nickname ?? this.name}] Hello!!`;
    }
}

const user = new User({
    age: 18,
});

console.log(user.hello());
// > [anonymous] Hello!!

Partial を試してみたんですが、絶対に欲しい値もオプショナルになってしまうので要望に合いませんでした

また、単純なpropertyの列挙だとメソッドまで含まれてしまうのでメソッドを除外しています

デフォルト値も定義できるので今のところ特に困ってません

NonFunctionPropertyNames などはここを参考にしました www.typescriptlang.org

Next.jsでページ遷移するときにMaterial UIのプログレスバーを表示する

はじめに

Nest.jsではページ遷移がシームレスに行われるのでプログレスバーを出してあげるとわかりやすいです

大体下記のパッケージを使うのが主流かと思いますが

個人サイトではよくMaterial-UIを使用しているのでそのパターンで実装をします

www.npmjs.com

コンポーネントの実装

下記の用にRouterのeventをハンドリングします

  • routeChangeStart ページ遷移開始時
  • routeChangeComplete ページ遷移完了時
  • routeChangeError ページ遷移中にエラーが起こったとき
import { LinearProgress } from '@material-ui/core';
import Router from 'next/router';
import React from 'react';

export const TransitionProgress = () => {
    const [progress, setProgress] = React.useState(false);

    const setEnabled = React.useCallback(() => setProgress(true), []);
    const setDisabled = React.useCallback(() => setProgress(false), []);

    React.useEffect(() => {
        Router.events.on('routeChangeStart', setEnabled);
        Router.events.on('routeChangeComplete', setDisabled);
        Router.events.on('routeChangeError', setDisabled);

        return () => {
            Router.events.off('routeChangeStart', setEnabled);
            Router.events.off('routeChangeComplete', setDisabled);
            Router.events.off('routeChangeError', setDisabled);
        };
    }, [setEnabled, setDisabled]);

    return progress ? <div style={{ position: 'fixed', top: 0, left: 0, right: 0 }}><LinearProgress /></div> : null;
};

LinearProgressの使い方はこちら material-ui.com

全ページに適用する

最後に _app.tsx に追加して終了です

import { AppProps } from 'next/app';
import React from 'react';
import { TransitionProps } from './TransitionProps';

const App = (props: AppProps) => {
    const { Component, pageProps } = props;

    return (
        <>
            <TransitionProps />
            <Component {...pageProps} />
        </>
    );
};

export default App;