OmniAICreator/Qiita-1.07M huggingface dataset:
自分のWebサイトにカラーテーマ実装したい

この記事は [Web グラフィックス Advent Calendar 2020](https://qiita.com/advent-calendar/2020/webgraphics) の4日目の記事です。

## はじめに
- 自分の制作したWebサイトやWebアプリにカラーテーマを導入したい！
- ダークモードとかライトモードとかいろんなカラーモード入れていいかんじにしたい！
- 色は自分で決めたい！
- 🐭🐮🐯🐰🐲🐍🐴🐏🐵🐔🐶🐗

という人に向けた内容です。デモを見せつつ紹介できたらと思います。

## どんなかんじなの

実際にみてもらった方が早いと思うので、自分のポートフォリオサイトにカラーテーマを導入してみました。
6種類ほど入れてみました。ポチポチで切り替えられます。＼ﾀﾉｼﾝﾃﾞｲｯﾃﾈ!!!!／
https://derennoportfolio.web.app/
![Group 8 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302304/06a56b05-82f9-3032-1ca8-005c7bc94dd0.png)

## どうやるの

先ほど、ポートフォリオサイトにカラーテーマ入れてみたやで！と書きましたが
こちらにも簡単なデモを作成しました。こっちの方がコード見られるもんね。

ボタンでカラーを切り替えることができます。

<p class="codepen" data-height="540" data-theme-id="default" data-default-tab="result" data-user="deren2525" data-slug-hash="MWjwxPJ" style="height: 540px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="【DEMO】Change Theme Color">
  <span>See the Pen <a href="https://codepen.io/deren2525/pen/MWjwxPJ">
  【DEMO】Change Theme Color</a> by Deren (<a href="https://codepen.io/deren2525">@deren2525</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

HTMLタグに属性を追加することができるので `:root` にカラーテーマ用の属性を追加します。
[element.setAttribute - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Element/setAttribute)

```js:main.js
// 上にあるデモから抜粋

// 初期状態
// HTMLタグに「theme」属性を追加。valueに「LIGHT」をいれる
document.documentElement.setAttribute('theme', 'LIGHT');

// 「LIGHT」テーマに切り替わるよ
function changeLight() {
  document.documentElement.setAttribute('theme', 'LIGHT');
}

// 「DARK」テーマに切り替わるよ
function changeDark() {
  document.documentElement.setAttribute('theme', 'DARK');
}
```
ボタンを押す度にクリックイベントが発火して `value` をコロコロ変えています。

---

色の切り替えはCSSの変数で切り替えています。
[CSS カスタムプロパティ (変数) の使用 - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/Using_CSS_custom_properties)

作りたいカラーテーマの数だけ、どんどん増やしてしまいましょう。
自分で色を決めるのは大変だけど自分で好きに決められるのって楽しいと思う。

```css:color.scss
/* 上にあるデモからカラーに関することだけ抜粋 */

/* 「LIGHT」テーマのカラー設定 */
:root[theme='LIGHT'] {
  --color-container: #F5F5F5;
  --color-main: #6D4C41;
  --color-sub: #FF9800;
}

/* 「DARK」テーマのカラー設定 */
:root[theme='DARK'] {
  --color-container: #37474F;
  --color-main: #64B5F6;
  --color-sub: #F5F5F5;
}

.container {
  background: var(--color-container);
}

.main-text {
  color: var(--color-main);
}

.sub-text {
  color: var(--color-sub);
}
```

---

もし、SCSSを使っていて設計的にCSS変数をあまりページで使いたくない！SCSSの変数を使っていたい！
という人は少し冗長になりますがSCSSの変数にCSS変数を定義してあげて、それをページ側で使ってあげるのがいいのかなと思います。**完全に個人の主観です。**

```scss:variable.scss
@import './color.scss';

$COLOR_CONTAINER: var(--color-container);
$COLOR_MAIN: var(--color-main);
$COLOR_SUB: var(--color-sub);
```

## おわりに
簡単な紹介になってしまいましたが、機会あれば是非とも活用してみてください〜
入社半年のインフラ未経験者がAWSのSAA認定を取ってみた

# はじめに
[フューチャーAdvent Calendar 2020](https://qiita.com/advent-calendar/2020/future) の4日目です。

こんにちは。
踊るエンジニア、木戸俊輔です。ダンスもプログラミングも両方楽しいです。
フューチャー株式会社に2020年4月、新卒入社し、今は[FutureVuls](https://vuls.biz/)という脆弱性管理サービスの開発をしています。もう2020年も終わりですね。
「今年の汚れ、今年のうちに」という言葉が好きなので、今年の学びを今年のうちに吐き出しておきます。

さて、FutureVulsはAWSを利用するSaaSサービスということもあり、先日、インフラ周りの知識と経験を得るためにAWSのSAA（ソリューションアーキテクト-アソシエイト）認定を取得しました。この記事では、インフラ系の知識が皆無だった私がSAA認定を取得するためにどんな勉強をしたのか、また、どんな知識やスキルが身についたかをお伝えしていきます。

- AWSの基礎を体系的に学びたい
- 気軽にAWS系の資格を取得したい
- 内容は決まってないけど、何かしら今後のためになることを学びたい

といった人におすすめです。

# SAA認定とは
SAA認定とは、AWS関連の技能を証明する認定の1つです。SAA認定では以下のような能力を検証します。

- 顧客要件に基づいてアーキテクチャ設計原則を使ったソリューションを定義する。
- プロジェクトのライフサイクル全体を通じて、ベストプラクティスに基づいた実装ガイダンスを組織に提供する。

認定を取得するために必要な技能レベルの目安として、1年間のAWSクラウドを使用した問題解決と解決策の実施における経験が推奨されています。もちろん、必須ではないため、AWSやインフラ基礎の知識・経験が無くても受講は可能ですが、その分ハードルがあがるのは間違いないでしょう。（確かに難しかったです。）
[AWS認定のサイト](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)にサンプル問題があがっていますので、どれくらいの難易度か気になる人は試しに解いてみてください。

↓このような問題が全部で65問出ます。（[SAA-C02 試験問題サンプル](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Sample-Questions.pdf)から抜粋）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/868829/51505d5c-c3a5-3793-61f0-f88dee893dc3.png)


# 学習方法
私は、[Udemyの対策講座](https://www.udemy.com/course/aws-associate/)を用いて学習しました。書籍を購入するか、AWSの公式ドキュメントを参照しながら独学で学ぶか、色々と悩みましたが、映像形式で学習できるのが個人的に一番楽でいいですね。しかもこちらの講座、ハンズオンが用意されており、AWSを全く触ったことのない人でも利用方法がわかりやすいようになっています。セール中だと安いので、個人的にとても良い選択だったと思います。

この講座ではEC2やS3、VPCといったAWSの主要サービスの理解から、AWSが提唱する設計原則やベストプラクティスに沿った設計思考を学んでいきます。動画は全部で30時間に満たないので、毎日2時間ずつ見れば2週間程度で視聴し終わります。ですが、ハンズオンで触れない細やかな説明部分も重要なので周回することがおすすめです。（偉そうに書いてる私は、一周した勢いで受けましたが落ちてしまいました。）講座の最後には模擬試験もついているので、この講座１つで試験対策がバッチリできます。
仕上げで、AWSの[サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Sample-Questions.pdf)を解いておくと自信がつくと思います。

# 試験を受ける
さて、知識が身についたら受験しましょう。テストセンターが空いていれば、基本的には好きな時に受験できます。
試験の結果はその場ですぐに確認できます。また、合格していると後日、下のような認定証がもらえます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/868829/cc5426d3-7d08-e240-1a70-537f0f36638f.png)

私が費やしたトータルの勉強時間は5,60時間くらいです。テストに合格するためだけなら、対策本で勉強するほうが早いかもしれませんが、ハンズオンなどを通してしっかりと理解することが大事だと思います。

# 身についた知識
AWSの主要サービスから、比較的最近のサービス、また、これらを用いたサービスの設計原則など幅広い知識を得ることができました。
学んだ事例をいくつか挙げておきますね。

- IAMを用いたAWSの権限管理設定
- EC2の適切なサーバー選択
- セキュアなVPCの構成
- 可用性とコストパフォーマンスを最大化するS3の選択と運用
- 利用目的に合ったデータベース選択
- スケーラブルなシステム構成
- 障害に備えたバックアップおよび復旧方法
- 環境設定の自動化

などなど。

# 最後に
講座を通した学習、および認定試験の受験によって、AWSの基礎知識だけでなく、インフラ全般の基礎知識を身につけられたと感じます。
クラウド技術が広く扱われる前はどのようにシステムを構成していたのか。それがクラウドに移り変わることでどのような恩恵を我々が受けられるのか。
IT業界に飛び込んだものの、どうやってインフラ知識を得ていこうか迷ってる方は、是非、取得を考えてみてください！
AWSはこの先も利用されることが多いでしょうし、他のクラウドサービスを利用する際も理解の助けとなることでしょう。
この記事を見て、私も気軽にチャレンジできそうだと、思ってくれる人が増えれば幸いです。
PHP7.4に移行後、CakePHP3.8で画像アップロードする際にエラーが出る

# 環境
- CakePHP 3.8
- josegonzalez/cakephp-upload : 4.0.1

# 症状
環境が PHP7.2 → PHP7.4 に変更になりまして。
PHP7.4 の状態で、CakePHP3.8 のアプリディレクトリで bin/cake cache clear_all をすると、なんかコンソールのモデルかなんかでエラーが出るようになりました。調べると、PHP7.4 に準拠してない書き方があるためだとわかったので、composer.lock を一度削除して、再度 composer install しました。キャッシュクリア時のエラーは無事なくなり、キャッシュクリアは問題なく出来るようになりました。

が、なぜか今度はアプリから画像のアップロードが出来なくなりました……。
エラーはこんな感じ。↓

```
2020-12-03 13:01:30 Error: [Error] Class 'League\Flysystem\Adapter\Local' not found (/var/www/myapp/vendor/josegonzalez/cakephp-upload/src/File/Writer/DefaultWriter.php:160)
```

# 原因（と対処法？）
アップロードで使っているのは
josegonzalez/cakephp-upload
なんですが、これが require としてるのが、

```
"require": {
    "cakephp/orm": "^3.5",
    "league/flysystem": "*"
},
```

問題はこっちの方。↓

```
"league/flysystem": "*"
```

league/flysystem が、今まで１系だったのに、つい最近２系が出たようで、composer install したせいで最新の ２系が入ったんですね。
そのせいで画像アップロードの際に josegonzalez/cakephp-upload から呼び出している League\Flysystem\Adapter\Local が無い！とエラーになっているようでした。確かに、League\Flysystem\Adapter は１系にしかない。なじょして……。

いや、まあ、だいぶファイル構造変わっちゃいましたしね……？？？
https://github.com/thephpleague/flysystem

さてしかし、これは困った…。
一時的な対応として、大本の composer.json でバージョンを指定してしまうというのは一つの手ですが。

```
"league/flysystem": "1.*",
```

ただ、josegonzalez/cakephp-upload さんが、league/flysystem の 2系 に合わせてバージョンアップした場合は、多分またその時にエラーになる。ツラい。
とりあえず、josegonzalez/cakephp-upload さんが対応してくれるのを待ちたい。
Google Chrome の拡張機能で Salesforce を便利に使おう

#Google Chrome-extension #
<ul>
        <li>
            <a href="https://chrome.google.com/webstore/detail/forcecom-logins/ldjbglicecgnpkpdhpbogkednmmbebec?hl=ja">Force.com LOGINS  </a>
            <br>各環境へのログインを補助するツール。
        <li>
            <a href="https://chrome.google.com/webstore/detail/salesforce-inspector/aodjmnfhjibkcdimpodiifdjnnncaafh?hl=ja">Salesforce inspector  </a>
            <br>SoqlEditやObjectBrowserのようなツール。
        <li>
            <a href="https://chrome.google.com/webstore/detail/salesforce-navigator/ecjmdlggbilopfkkhggmgebbmbiklcdo">Salesforce Navigator  </a>
            <br>SFDCの各種リンクに直接ジャンプできるツール。
            <br>SFDCの画面をChromeで表示している際に、Shift+Ctrl+Spaceを押下で入力バーが表示され、入力に応じたジャンプ先候補が表示される。
        </li>
        <li>
            <a href="https://chrome.google.com/webstore/detail/take-webpage-screenshots/mcbpblocgmgfnpjjppndjkmgjaogfceg?hl=ja">FireShot  </a>
            <br>キャプチャ取得ツール。
            <br>作成した画像をコピーし、Excelにビットマップ貼り付けが必要です。
        </li>
        <li>
            <a href="https://chrome.google.com/webstore/detail/salesforce-colored-favico/peohlnebahcddpmfaplmilpkgbkkcdho?hl=en">Salesforce Colored Favicons  </a>
            <br>表示しているSFDC環境ごとに異なる色を、Chromeタブのアイコンに付与する。
            <br>どの環境にて作業しているかが判別し易くする。
        </li>
        <li>
            <a href="https://chrome.google.com/webstore/detail/salesforce-api-fieldnames/oghajcjpbolpfoikoccffglngkphjgbo">Salesforce API Fieldnames  </a>
            <br>APIフィールドの名前とsalesforceの詳細ページのラベルを切り替える。
        <li>
            <a href="https://chrome.google.com/webstore/detail/salesforce-advanced-code/lnkgcmpjkkkeffambkllliefdpjdklmi">Salesforce advanced Code searcher  </a>
            <br>Salesforceインスタンスのコードコンポーネントを検索できます。
        <li>
            <a href="https://chrome.google.com/webstore/detail/salesforce-devtools/ehgmhinnhggigkogkbhnbodhbfjgncjf">Salesforce DevTools  </a>
            <br>ER図自動生成機能、オブジェクト定義書（Excel）の自動生成機能、テストコード・SOQLのクィック自動生成機能等。
        </li>
      </ul>

#使えそうなリンク#
<ul>
        <li><a href="http://hensumei.com/kanji-romaji">Variable name creation</a><br>日本語をローマ字に変換してくれるサイトです。</li>
        <li><a href="https://hogehoge.tk/personal/">疑似個人情報データ生成</a><br>名前、名前ｶﾅ、生年月日、住所、電話番号などの擬似データをランダムで作成してくれます。</li>
        <li><a href="https://docforce.herokuapp.com/">Docforce</a><br>Salesforce環境の設計書作成を自動で作成してくれます。</li>
        <li><a href="https://demo-creator-suite.herokuapp.com/login.php">Demo Creator Tool Suite</a><br>Salesforceの項目を一気に複数作成することができます。</li>
        <li><a href="http://tech-unlimited.com/urlencode.html">URLエンコード・デコード</a><br>URLをエンコード（ あ → %E3%81%82 ）、またデコード（ %E3%81%82 → あ ）する事ができます。</li>
        <li><a href="https://workbench.developerforce.com/login.php">workbench</a><br>RESTエクスプローラを使用して応答データを取得できます。</li>
      </ul>
PlayCanvasにGoogle Analyticsを埋め込む方法

Google Analyticsを埋め込む方法です。PlayCanvasではそのまま、`<script>`タグを埋め込むことが出来ないので埋め込む方法を紹介します。

#### 1. Google Analyticsの公式サイトからタグを用意します

例

```javascript

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxx"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-xxxxxxxx');
</script>
```

#### 2. PlayCanvasのSETTINGS　→ EXTERNAL SCRIPT機能を使ってAnalyticsのタグを追加します。
![スクリーンショット 2020-12-03 14.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257048/16b73917-1e00-c9d5-cfc8-937ecfb17989.png)

`https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxx`

#### 3. `dataLayer`, `gtag`...の4行のスクリプトをPlayCanvasに追加します。
![スクリーンショット 2020-12-03 14.28.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257048/ceec6da0-ae0e-e24c-5316-d87981c2e959.png)

このスクリプトを追加します。

```analytics.js
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-xxxxxxxx');
```


これでGoogle Analyticsの埋め込みが出来ます。

### Googleタグマネージャーを読み込む
Google Tagmanagerを埋め込むにはこちらのスクリプトをエディターに追加し、アセットの読み込みタイミングを「After Engine」にして保存します。
```javascript
function initGoogleTagManager(window, document, scriptTag, dataLayer, id) {
    window[dataLayer] = window[dataLayer] || [];
    window[dataLayer].push({
        'gtm.start': new Date().getTime(), // 新しいオブジェクトに2つのプロパティを追加する
        event: 'gtm.js'
    });

    var firstScriptTag = document.getElementsByTagName(scriptTag)[0];
    var newScriptTag = document.createElement(scriptTag);
    var dataLayerName = dataLayer != 'dataLayer' ? '&l=' + dataLayer : '';

    newScriptTag.async = true;
    newScriptTag.src = 'https://www.googletagmanager.com/gtm.js?id=' + id + dataLayerName;
    firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}

initGoogleTagManager(window, document, 'script', 'dataLayer', 'GTM-xxxxx');
```
ログインシェルがbashの環境でzshの算術演算を使う

ログインシェルがbashの環境でコマンドラインからzshの組み込み算術演算を使ったり、bashスクリプトの中で算術演算だけzshのものを使いたい場合のメモ

# bashとzshの算術演算の違い

bashもzshも組み込みの算術演算があり電卓代わりに使うには`$((...))`で囲むだけなので`expr`や`bc`コマンドより簡単なので便利である。しかしながら、zshの算術演算は小数点演算、`**`によるべき乗計算、指数形式の数値の読み込みなど色々できるのに対し、bashの組み込み算術演算は整数演算しかできないのでログインシェルがbash環境のサーバーでは組み込み算術演算を使うには制約が多く不便である。

```console:zsh
$ echo $((1+2))
3

$ echo $((0.5+2))
2.5

$ echo $((1 + 2e+3))
2001.

$ echo $(( 2.0**(1.0/3.0) ))
1.2599210498948732
```

```console:bash
$ echo $((1+2))
3

$ echo $((0.5+2))
bash: 0.5+2: syntax error: invalid arithmetic operator (error token is ".5+2")

$ echo $((1 + 2e+3))
bash: 1 + 2e: value too great for base (error token is "2e")

$ echo $(( 2.0**(1.0/3.0) ))
bash: 2.0**(1.0/3.0) : syntax error: invalid arithmetic operator (error token is ".0**(1.0/3.0) ")
```

# bashのログインシェルでzshの算術演算を使う

zshがインストールされているものの、ログインシェルにbashが推奨されている環境やbashスクリプトだが算術演算だけzshの組み込みを使いたい場合が対象。

bashからzshのコマンドオプションを指定して実行するだけ。

```console:bash
$ zsh -c 'echo $((0.5+2))'
2.5
```

シングルクォーテーションでなくダブルクォーテーションを使ってしまうと先に変数が展開されるので注意。

```console:bash
$ zsh -c "echo $((0.5+2))"
bash: 0.5+2: syntax error: invalid arithmetic operator (error token is ".5+2")
```

## bashで指定した変数を使う場合

シングルクォーテーションで指定してbashの変数展開をさせないようにしたが、zshのコマンドオプションの引数として渡すことができる。

```console:bash
$ a=1e+3
$ b=0.25

# 変数展開されないので反映されない
$ zsh -c 'echo $(($a+$b))'
zsh:1: bad math expression: operand expected at end of string

# 引数として変数を渡し、算術演算内の変数名は引数番号を指定する
$ zsh -c 'echo $(($0+$1))' $a $b
1000.25
```
プログラミング（IT）初心者がgoroutineを理解しようと頑張ってみた。

#はじめに
LaravelやRailsなどのMVCフレームワークでのwebアプリケーション作成くらいしかしたことない自分がGoを自主学習してみた。

PHPやRubyと重複してるような文法はある程度把握できたが、goroutineが出た瞬間に何が何だか分からなかったので、理解のプロセスをまとめてみた。


#学習の流れ

##１、A tour of goでの解説を噛み砕いてみた

```
goroutine (ゴルーチン)は、Goのランタイムに管理される軽量なスレッドです。
```

[ランタイムとは](https://wa3.i-3-i.info/word13464.html)

[スレッドとは](https://wa3.i-3-i.info/word12453.html)
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典（引用）


上記二つの記事を元に噛み砕いた結果
**goroutine (ゴルーチン)は、Goが持つ、軽いプログラムの実行手段（並行処理）。**

みたいな感じでしょうか。
Goが凄いと言われる理由にもなるgoroutineの理解を少し深めてみました。

##２、goroutine (ゴルーチン)の並行処理についてもう少し理解を深めてみた

理解を深める際に
[goroutineはなぜ軽量なのか](https://christina04.hatenablog.com/entry/why-goroutine-is-good)という記事を参考にしました。


##goroutineが軽量な理由
・プログラムを実行する際のメモリ使用量が低い
・プログラムを切り替える際のコストが低い
という点があります。
それぞれについてまとめました。

###スレッドに比べてメモリ使用量が低い
プログラム実行時にメモリ領域が利用されます。
その領域の利用のされ方は大きく三つある
１、スタック領域（コンパイラやOSが勝手に利用領域を決めちゃう）
２、ガード領域（スタック領域とヒープ領域が重複されないように壁を作ってる）
３、ヒープ領域（プログラムが意図的に利用領域を調整できる）

上記の問題点として
・スタック領域が多めに確保しちゃう
・ガード領域がプログラム実行が行われる度にできちゃう
↓イメージ図
![スクリーンショット 2020-12-03 11.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640569/e6734e0b-c074-dee1-dde0-cccd798af2c1.png)
イベントループなしでのハイパフォーマンス – C10K問題へのGoの回答 | POSTD（引用）

完結に言うとgoroutineを利用することで、
**スタック領域を最小限にするかつ、ガード領域を無くし、処理を早くすることができるらしい**
凄いね！

###プログラムを切り替える際のコストが低い
プログラムを並行処理するにあたって、スイッチングコストという負荷がかかる。
goroutineは現行で一番早いとされているM:N（ハイブリッドスレッディング）というものを採用されている。
このM:Nの欠点としてスケジューラ（プログラムに優先順位をつける）が複雑になるが、それはGO言語自体の機能で補完されている。

[詳細はこちら](https://qiita.com/takc923/items/de68671ea889d8df6904)

とても簡単に言うと
**M:Nは処理めっちゃ早いんだけれども、プログラムの処理を行う順序を意図的に行えないという欠点がある。
しかし、Go言語は順序を意図的に行える機能がついていて、その欠点はないも同然！！**


#最後に
いかがでしょうか。
Goの何が凄いかを理解しないまま使うのは恥ずかしいと思い、goroutineについて調べてみました。
思ったよりも自分の知識の補完ができた上にGoが凄い理由を話せるようになってよかったです。

たくさんの参考文献を利用させていただきました。ありがとうございます！！！！！
Rakeの使い方を学ぼう！〜gitの自動化編〜



# 目次

このページではrakeコマンドについて以下の順を追って説明する．

-   [rakeの基本](#rakeの使い方)
-   [タスクを階層化する](#タスクを階層化する)
-   [gitを自動化](#gitを自動化)


# rakeの基本

rakeコマンドというものがある．これはカレントディレクトリにあるRakefileの中身を実行するコマンド．

たとえば以下のようにRakefileに書いておく．

```ruby:Rakefile
task default: :hello #何も指定しなければここが動作する

desc "hello" #description 説明の部分
task :hello do #rakeの後にhelloと指定するとここが動作する
  puts "Hello Rake!!"
end
```

rakeだけ入力し実行するとdefaultで設定されているhelloの部分が実行される．

今はhelloだけだが，タスクを増やした場合その一覧を表示するには **rake -T** とする．

[目次へ](#目次)


# タスクを階層化する

rakeで実行するタスクの種類を増やす場合は **namespace** を以下のように使用する．

```ruby:Rakefile
task default: 'basic:hello'

namespace :basic do
  desc "hello"
  task :hello do
    puts "Hello Rake!!"
  end
end

namespace :one do
  desc "one"
  task :foo do
    puts "test1"
  end
  namespace :two do
    desc "one two"
    task :hoge do
      puts "test2"
    end
  end
end
```

    $ rake -T
    rake basic:hello   # hello
    rake one:foo       # one
    rake one:two:hoge  # one two

[目次へ](#目次)


# gitを自動化

gitを共有する際，

    $ git pull origin main
    $ git add -A
    $ git commit -m "hoge"
    $ git push origin main

を実行するがいちいち打つのがめんどくさい．

そこで，rakeコマンドでこれらを実行できるようにする．

そのために **system** という関数を使用する．これはsystemコマンドを起動することができる関数である．

```ruby:Rakefile
desc 'git pull push'
task :push do
  p comm = "git pull origin main"
  system comm
  p comm = "git add -A"
  system comm
  p comm = "git commit -m #{ARGV[1]}"
  system comm
  p comm = "git push origin main"
  system comm
  exit
end
```

    $ rake push

とコマンドに入力することでgitの一連の動作を自動で行うことができるようになった．

[目次へ](#目次)


# まとめ

今回はrakeコマンドでgitの一連の動作を自動化した．


# 参考

以下を参考にした．

-   [ruby rakeの使い方](https://qiita.com/abcb2/items/9905449ab3fcf5d27ace)
-   [Rakeで自動化&Export](https://qiita.com/evendemiaire/items/4dbcfb1819fc23ac8ba9)#+begin\_src ruby:check\_leap\_year.rb



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/rakefile.org
Rubyで閏年判定プログラムを作成しよう！



# 目次

このページではRubyを使用し閏年の判定プログラムを作成する．

-   [問題](#閏年判定プログラム)
-   [基本的な動作](#基本的な動作の作成)
-   [例外処理](#例外処理)
-   [複数年の判定](#複数年の判定)
-   [methodの利用](#methodの利用)


# 閏年判定プログラム

以下の問題をRubyで書いてみる．

    入力した年が閏年かを判別し表示するプログラムの作成する．
    
    ただし，100で割り切れる年は閏年ではないが，400で割り切れる年は閏年であることを組み込む．

以上をテスト駆動開発の順を追って作る．


## 基本的な動作の作成

まずは，例外は考えず入力した年が閏年かどうかを判別するプログラムを作成する．

簡単に書くと以下のようになる．

```ruby:check_leap_year.rb
p year = ARGV[0].to_i
if year % 4 == 0
    p ture
end
```

このプログラムに2004と入力すると

    $ ruby check_leap_year.rb 2004
    2004
    true 

と表示される．

このままだと1999など条件を満たさない年を入力しても何も表示されないので，その部分を作成する．

```ruby:check_leap_year.rb
p year = ARGV[0].to_i
if year % 4 == 0
    p ture
else
    p false
end
```

このプログラムに1999と入力すると

    $ ruby check_leap_year.rb 1999
    1999
    false 


## 例外処理

閏年の条件は

    ・西暦年号が4で割り切れる年を閏年とする．
    ・西暦年号が100で割り切れて400で割り切れない年は平年とする．

先程のプログラムに上記の例外処理を組み込む．

```ruby:check_leap_year.rb
p year = ARGV[0].to_i
if year % 400 == 0
    p ture
elsif year % 100 == 0
    p false
elsif year % 4 == 0
    p true
else
    p false
end
```

これに1900,2000を入力すると

    $ ruby check_leap_year.rb 1900
    1900
    false
    
    $ ruby check_leap_year.rb 2000
    2000
    true

となる．ひとまずこれで例外処理まで実装できた．


## 複数年の判定

一年ずつ入力して起動して．．．を繰り返すのは少しめんどくさい．

なので配列を利用し，loopを回してみる．

```ruby:check_leap_year.rb
[2004,1999,1900,2000].each do |year|
    p year
    if year % 400 == 0
	    p ture
    elsif year % 100 == 0
	    p false
    elsif year % 4 == 0
	    p true
    else
	    p false
    end
end
```

このプログラムを実行すると

    $ ruby check_leap_year.rb
    2004
    true
    1999
    false
    1900
    false
    2000
    true

となる．


## methodの利用

先程のプログラムの判定する部分をmethodにして取り出してみる．

```ruby:check_leap_year.rb
def leap?(year)
    if year % 400 == 0
	    true
    elsif year % 100 == 0
	    false
    elsif year % 4 == 0
	    true
    else
	    false
    end
end

[2004,1999,1900,2000].each do |year|
    p year
    p leap?(yaer)
end
```

このプログラムを実行すると

    $ ruby check_leap_year.rb
    2004
    true
    1999
    false
    1900
    false
    2000
    true

これでも動作するが，さらに「case」という物を使うとさらに美しくなるようだ．

```ruby:check_leap_year.rb
def leap?(year)
  case
  when year % 400 ==0 ; true
  when year % 100 ==0 ; false
  when year % 4 ==0 ;   true
  else ;                false
  end
end

[2004 1999, 1900, 2000].each do |year|
  p year
  p leap?(year)
end
```

このプログラムを実行すると

    $ ruby check_leap_year.rb
    2004
    true
    1999
    false
    1900
    false
    2000
    true

以上で完成．


# まとめ

今回はRubyで閏年の判定プログラムを作成した．


# 参考

以下を参考にした．

[Rubyのお勉強＜制御構造\_Ifとか＞](https://qiita.com/evendemiaire/items/4f9550981bd3d6017cdd)



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/leap_year.org
assert_equal関数を作成する



# 目次

このページではassert equalというequalかどうかを確かめる関数を以下の順をおって説明する．

-   [assert\_equalの基本部分を作成](#assert\_equalの基本部分を作成)
-   [色を付ける](#色を付ける)
-   [出力をrichにする](#出力をrichにする)
-   [重複箇所を整理](#重複箇所を整理)
-   [重複実行の予防](#重複実行の予防)


# assert\_equalの基本部分を作成

assert equalの基本的な動作をする関数を作成してみる．

引数として確認するもの(expected)と結果(result)を与え，関数内でそれらが等しいかどうかを確認する．以下はその内容．

```ruby:assert_equal.rb
def assert_equal(expected, result)
    return expected == result
end
```

これで引数が等しければtrue，そうでなければfalseを返すことができるようになった．

[目次へ](#目次)


# 色を付ける

次に先程の関数の出力に着色できるようにして，見やすくしてみる．

そのために **colorize** というものを使用する．

```ruby:assert_equal.rb
require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.green
  else
    puts 'false'.red
  end
end

assert_equal(1, 1)
```

これを実行すると緑色でtrueと表示される．

もしcolorizeがないと怒られたら

    $ gem install colorize 

でinstallする．

この関数で

```ruby:assert_equal.rb
assert_equal(1, 2)
```

とすると，赤色でfalseと表示される．

ちなみに，

    $ irb
    irb(main):001:0> require 'colorize'
    => true
    irb(main):002:0> String.colors
    => [:black, :light_black, :red, :light_red, :green, :light_green, :yellow, :light_yellow, :blue, :light_blue, :magenta, :light_magenta, :cyan, :light_cyan, :white, :light_white, :default]

で，何色にcolorizeできるかが分かる．

[目次へ](#目次)


# 出力をrichにする

もう少し出力をrichにする．

-   引数でとってきた，expected, resultの値をそのまま出力
-   どうなったかを記述

```ruby:assert_equal_ro.rb
require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts "expected :: #{expected}"
    puts "result   :: #{result}"
    print "succeeded in #{__method__}.\n".green
  else
    puts "expected :: #{expected}"
    puts "result   :: #{result}"
    print "failed in #{__method__}.\n".red
  end
end

assert_equal(1,1)
assert_equal(1,2)
```

    $ ruby assert_equal_ro.rb
    expected :: 1
    result   :: 1
    succeeded in assert_equal.
    expected :: 1
    result   :: 2
    failed in assert_equal.

となった．

[目次へ](#目次)


# 重複箇所を整理

先程のコードでは重複している部分があるのでそれを別の関数に移しておく．

```ruby:assert_equal_ro2.rb
require 'colorize'

def puts_value(expected, result)
    puts "expected :: #{expected}"
    puts "result   :: #{result}"
end

def assert_equal(expected, result)
    puts_value(expected, result)
    if expected == result
      print "succeeded in #{__method__}.\n".green
    else
      print "failed in #{__method__}.\n".red
    end
  end
assert_equal(1,1)
assert_equal(1,2)
```

[目次へ](#目次)


# 重複実行の予防

このコードは今後繰り返し使用するようなので，そのための準備をしておく．

colorizeと同じようにrequireで呼び出す．同じdirectoryにコピーして使用する．

たとえば，

    require './assert_equal'
    
    assert_equal(2, 1*2)
    assert_not_equal('bob', 'bob2')

というように使う．

しかし，先程のコードには関数を実行する部分があるのでそれを回避したい．そこで使えるのが以下の構文だ．

```ruby:
if $PROGRAM_NAME == __FILE__
  assert_equal(1, 1)
  assert_equal(1, 2)
  assert_not_equal(1, 2)
  assert_not_equal(1, 1)
end
```

これを書いておくことで別ファイルから呼び出した時にifの中が実行されなくなる．

[目次へ](#目次)


# まとめ

assert\_equal関数を作成した．


# 参考



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/assert.org
Rubyの基礎文法



# 目次

今回は，Rubyの基本文法の

-   [出力](#出力する)
-   [入力](#入力する)
-   [Method](#method)
-   [ifなどの制御構造](#ifなどの制御構造)

について説明する．


# Rubyの基本文法を学ぼう


## 出力する

プログラム言語を学ぶ際に必ず通る道「Hello World」を表示してみよう．Rubyには出力だけで何種類もの方法があるようだ．代表的なものを列挙してみる．

| 表記方法| 末尾に改行| 表示形式           |
|:------|:------|:-------------------|
| print | 入れない| 文字列             |
| puts  | 入れる| 文字列             |
| p     | 入れる| 型情報(文字列型，整数型)をそのまま|

実行してみると．．．

```ruby
print "Hello "
print "World "
#=> Hello World

puts 'Hello '
puts 'World ' 
#=> Hello 
#=> World

p 'Hello '
p 'World '
#=> "Hello "
#=> "World "
```

〜「p」について〜

「p」の後ろに文字列がくると「””」で囲まれて表示され，数字がくると何もつかずそのまま表示される．

つまり，表示するものがどのような種類のものかを見た目で分かるようにする機能がついているようだ．

```ruby
p "99"
p 99
#=> "99" #文字列として表示
#=> 99　 #数値として表示　
```

[目次へ](#目次)


## 入力する

出力と同様に複数の入力方法があるのでそれらを並べてみる．

| 表記方法    | 出力内容       |
|:------------|:---------------|
| gets()      | キーボードから(文字列)|
| gets.to\_i()| キーボードから(整数)|
| gets.to\_f()| キーボードから(浮動小数点)|
| ARGV[引数番号]| コマンドラインの引数から|

まず，キーボードからの入力について．

「gets」を使用すると基本的に文字列として受け取る．

必要に応じて型を指定する方法をとる．

```ruby:gets.rb
str = gets()
num = gets.to_i()
p str
p num
```

    $ ruby gets.rb
    test 　　　 #自分の入力した文字
    99 　　　　 #自分の入力した文字
    "test\n"   #出力
    99 　　　　　#出力

コマンドラインの引数を受け取る方法は以下の通り．

```ruby:argv.rb
p ARGV[0]
```

    $ ruby argv.rb test
    "test"

[目次へ](#目次)


## Method

関数などをRubyではmethodと呼ばれるもので定義する．

例えば，引数を受け取りその引数を表示するmethodは次のようになる．

```ruby:method.rb
def hello(name)
    p name
end
```

これを使い，コマンドラインの引数を表示するには次のようにすれば良い．

```ruby:method.rb
def hello(name)
    p name
end

name = ARGV[0]
hello(name)
```

    $ ruby method.rb test
    "test"

[目次へ](#目次)


## ifなどの制御構造

条件分岐としてif-elsif-else-endが用意されている．

書き方は以下の通り．

```ruby
if 式 [then]
  式 ...
[elsif 式 [then]
  式 ... ]
...
[else
  式 ... ]
end
```

[目次へ](#目次)


# まとめ

今回はRubyの基本中の基本の文法をまとめた．

次回はこれらを使用し閏年の判別プログラムを書いてみる．


# 参考

以下のサイトを参考にした．

-   [【Ruby入門】初心者でもわかる基礎文法まとめ](https://www.sejuku.net/blog/107088)
-   [【Ruby超入門】print、puts、pの違い](https://yukimasablog.com/ruby-print-puts-p)



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/ruby_grammer.org
Qiitaの使い方を学ぼう!



# 目次

このページでは，

-   [org-modeの基本的な文法一覧](#org-modeの基本的な文法一覧)
-   [ページ内リンク](#ページ内リンク)
-   [注釈] (#注釈)
-   [折り畳み](#折り畳み)
-   [コメントアウト](#コメントアウト)

の書き方についてまとめる．


# org-modeの基本的な文法一覧


## 文法一覧表

よく使用する文法を以下の表にまとめた．

|         | orgの記法                |
|:--------|:-------------------------|
| *斜体*  | `/斜体/`                 |
| **太字**| `*太字*`                 |
| 下線    | `_下線_`                 |
| ~~打ち消し~~| `+打ち消し+`             |
| コマンド| `=code=`                 |
| 文章タイトル| `#+TITLE: TITLE`         |
| 見出し  | `* 見出し`               |
| 番号つき見出し| `1. 1st`                 |
| 箇条書き| `- 1st`                  |
| 定義リスト| `DEF :: Something`       |
| リンク  | `[[表示する文章][http://---]]`|
| 水平線  | `------`                 |
| 脚注    | `[fn:: インライン脚注]`  |
| コメント| `# コメント`             |

[目次へ](#目次) 


# ページ内リンク

例えば，

[このページの上にある「目次」に移動するためのリンク](#目次)

のようにページ内を移動する方法を紹介する．

    [表示する文章](#飛びたい見出しのタイトル)

基本的にはこのように書くと目的の見出しに飛ぶことができる．

．．．はずだった．

まれに飛ぶことができない場合がある．その例と対処法を以下にまとめる．


## 英字の大文字を使っている場合

目次で大文字を使っている場合は全て小文字にすると上手くいく．

    [大文字ABCは小文字abcで書く](#大文字abcは小文字abcで書く)


## 空白を使っている場合

半角空白を使っている場合は空白の部分をハイフン-で置き換える

    [空白 を 使っている時](#空白_を_使っている時)

全角空白を使っている場合は空白の部分を省略

    [空白　を　使っている時](#空白を使っている時)


## アンダーバー\_とハイフン-以外の記号を使っている場合

半角記号!@#$%^&\*()+|~=\`[]{};':",./<>?は省略する

    [半角記号!@#$%^&*()+|~=`[]{};':",./<>?は省略](#半角記号は省略)

全角の場合も同様．


## 上記を考えずにリンクを貼る技

上にいろいろと制約を書いたが，これを気にせずリンクを貼る方法があった．

見出しを作成すると画面右側に目次が表示されるようになっている．

そこをクリックするとページ内リンクと同じ動作をするが，飛んだ先でURLを確認すると上記のルールに沿った書き方で表示されている．

たとえば，右の「目次」をクリックして目次まで飛んだ際，

「<https://qiita.com/midoriyanagi/items/a4f6bc82488b25ffd48e#目次>」

というURLになる．この後半の「＃」以下をページ内リンクの書き方に沿って記載することで，何も考えず脳死でリンクを貼ることができる．

非常に便利．最高．上のやつ書かんでも良かったまである．

[目次へ](#目次)


# 注釈

言葉の説明などをしたい場合に使う．例えば

注釈1[^1]，注釈2[^2]

のようになる．

[^1]: 注釈1の説明の部分はここ

[^2]: 注釈2の説明の部分はここ

これは以下のように表記する．

    注釈部分:注釈1[^1]
    説明部分:[^1]: 注釈1の説明の部分はここ

[目次へ](#目次)


# 折り畳み

例えば，

<details><summary>折り畳みの例</summary>折り畳んだ文章がここに出るよ</details>

のように文章を隠しておき整理することができる．書き方は以下の通り．

    <details><summary>折り畳みの例</summary>
    折り畳んだ文章がここに出るよ
    </details>

[目次へ](#目次)


# コメントアウト

コメントアウトする場合はHTMLのコメントアウトの方法を使うらしい．書き方は以下の通り．

    <!-- (コメントアウトしたい内容) -->

[目次へ](#目次)


# まとめ

今回は，Qiitaをorg-modeで書く場合に使う文法についてまとめた．(どうやらマークダウン方式の書き方が使えるようになったらしい．)


# 参考

以下のサイトを参考にした．

-   [Org-modeの一覧](https://qiita.com/anmint/items/a720ff2e56138b8514eb)
-   [[Qiita Markdown記法]ページ内リンク・注釈・折りたたみ等](https://qiita.com/aymikmts/items/71e550bf2c10f36883e9)
-   [Qiita Markdownのページ内リンクの罠](https://qiita.com/hennin/items/7ee58dd7d7c013a23be7)



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/qiita_grammer.org
Happy Elementsの仕事環境について

この記事はHappy Elements Advent Calendar 2020の16日目の記事になります。

# はじめに
Happy Elements株式会社の人事担当です！
非エンジニアである為、技術的な記事発信はできないのですが。。。

代わりに、弊社での**仕事環境**についてご紹介させて頂こうと思います♪٩(ˊᗜˋ*)و

それでは、最後までお付き合いいただけますと幸いです。

# 仕事環境
## 【支給機材】
### ■PC
社内のエンジニアに対しては、会社標準機として下記スペックのPC
を支給させて頂いております！
社内の場所を問わず、自由にお仕事ができるよう、弊社では全員ラップトップとなっております。
※一部、3Dを扱う方に関しては+デスクトップも支給
※随時、スペック見直し行っております。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/34eecfe2-8e5c-b655-135e-6a9506c57d8a.png" width=75%>


| 項目 | 詳細 |
|:-:|:------------:|
| 機種名 | Apple MacBook Pro (16 インチ) | 
| CPU | 2.3GHz 8コアIntel Core i9プ‍ロ‍セッサ（Turbo Boost使用時最大4.8GHz） | 
| メモリ | 32GB 2,666MHz DDR4メモリ | 
| ストレージ | 1TB SSDストレージ | 
| グラフィック | Radeon Pro 5500M（4GB GDDR6メ‍モ‍リ搭載） | 

■周辺機器
![202012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/50776365-978e-6cb3-2376-53547df58468.jpeg)

希望者には、液晶ディスプレイも会社から支給！
キーボード・マウスも、会社にてご用意しておりますが、
ご自身でこだわりのあるものの持ち込みも可能です！！

その他、音楽聴きながらの作業や、研究用に他社ゲームをプレイするなど、働き方も多様！


## 【設備】
### ■カフェスペース
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/7d9d8051-4ecb-8853-2caf-910f7393b36d.jpeg" width=75%" width=75%>

### ■デスク・アーロンチェア
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/3bd15fff-49d4-4a95-8fac-fb15ecbbaec3.jpeg"width=75%>

広々とリラックスしてお仕事ができるよう、
ひとり1台ずつ、十分なスペースを確保したデスクにアーロンチェアをご用意しております！

ちなみに。。。
執務スペースはプロジェクトごとに部屋が分かれており、
社内は土足厳禁！靴を脱いでリラックスして働ける環境です！！


## 【福利厚生】
■スキルアップサポート
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/1d0de528-d553-c140-7676-3252d2026995.jpeg" width=75%>
技術向上や情報共有を目的として、社内にてエンジニア共有会の実施や
社外勉強会への参加補助、その他、資料・技術書の購入などを積極的に行っています。

### ■フリードリンク
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/f0687620-0fbb-44f9-8547-be999bdaddf0.jpeg" width=75%>

コーヒーや清涼飲料水、野菜ジュースなどが飲み放題の制度です。毎日ほぼ全員のスタッフが利用しています。
勤務中に飲み物を社外に買いに行く時間や手間を省き、よりものづくりに集中してほしいという想いから導入されました。

また、社内にはバーも設置されており、業務終了後にアルコール類を飲むことも可能です。


### ■社内交流イベント
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924950/8f2d7309-e878-61cd-0966-050979786a10.jpeg" width=75%>

社員旅行や、BBQ、全社イベントなど、社員同士の交流を目的としたイベントやレクリエーション企画を実施しています。

※基本的に**自由参加**ですので、こういった交流が苦手な方にも配慮してます！

## 【その他】
### ■勤務時間
弊社ですが、**フレックス制**を採用しており、**コアタイムが11:00～16:00**ですので、朝は比較的ゆっくり出社できます！
(多くの方が11時前に出社してます。)

また、コアタイムは16時までなので、プライベートの予定も立てやすく、フレキシブルに働ける環境をご用意しております。

##最後に
弊社ですが、
**【ユーザーファーストなものづくりのための、クリエイターファーストな組織を目指す】**
を経営理念に掲げており、

今回は一部のみのご紹介となりましたが、これからも、クリエイターにとって**理想的**な環境作りを目指してまいりますので、またどこかで情報発信していければと考えております！

---

Happy Elements株式会社 カカリアスタジオでは、
いっしょに【熱狂的に愛されるコンテンツ】をつくっていただけるメンバーを大募集中です！

もし弊社にご興味持っていただけましたら、是非一度、下記採用サイトをご覧ください。
[【Happy Elements株式会社 採用特設サイト】](https://recruit.happyelements.co.jp/)
マルチスケールシミュレーション特論



# Introduction

[マルチスケールシミュレーション特論](https://qiita.com/daddygongon/private/48619d343221f405b6d7)の講義内容をまとめる．


# Lecture

-   [第1回] [Qiitaの使い方を覚えよう!](https://qiita.com/midoriyanagi/private/4fa0ffb41545bd7ecda2)
-   [第2回] [Rubyの基礎文法を覚えよう!](https://qiita.com/midoriyanagi/private/fef033fbfa51ddc57cd4)
-   [題3回] [Rubyで閏年判定プログラムを作成しよう！](https://qiita.com/midoriyanagi/private/c60e85ea4c3ee90847a3)
-   [第4回] [Rakeの使い方を学ぼう！〜gitの自動化編〜](https://qiita.com/midoriyanagi/private/9acf338f9205ba934f81)
-   [第5回] [assert\_equal関数を作成する](https://qiita.com/midoriyanagi/private/41689ed2157ad05a8cda)



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/README.org
Node.jsアプリのOpenID Connect認証連携

# はじめに
自作のNode.jsアプリをOpenID Connectプロバイダーと連携させて認証機能を実装するためのNode.jsアプリの作り方について説明します。全体の流れは以下の通りです。

1. 前提の確認
2. OpenID Connectプロバイダーへのアプリの登録
3. Node.jsアプリのコーディング

# 前提
この記事での環境の前提は以下の通りです。ただし、なるべく環境依存せず汎用的になるよう記事を書いています。コードの要所部分のみを説明しています。

- Node.js
    - この記事では、npmモジュールのpassport-ci-oidcを利用します。
    - npmモジュールのexpressやpassportも利用しますが、前提知識の説明を省略いたします。
- OpenID Connectプロバイダー
    - OpenID Connectとは何かなど前提知識の説明を省略いたします。
    - どのプロバイダーでもアプリの作り方の大まかな流れは変わりませんが、プロバイダーが利用方法を細かくガイドしている場合があります。特にどのnpmモジュールを利用するかは、プロバイダーの仕様により決まることがあります。
    - この記事では、IBM Security Verifyという製品で作られたプロバイダーを利用しています。今回利用するプロバイダー自体の構築や運用には携わっておらず、あくまで一利用者の立場です。

# OpenID Connectプロバイダーへのアプリの登録
プロバイダーが提供するポータルへアクセスし識別可能にするためのアプリ名などを登録すると、アプリが連携するのに必要な情報が払い出されます。主な項目は以下の通りです。

- 文字列として払い出される項目:
    - Client ID
    - Client Secret
- URL文字列として払い出される項目:
    - Authorization Endpoint
    - Token EndPoint
    - UserInfo EndPoint
    - Introspection EndPoint
    - Discovery Endpoint
    - Issuer

# Node.jsアプリのコーディング
アプリのプロジェクトディレクトリで以下のコマンドを実行し、npmモジュール passport-ci-oidc をインストールします。コマンド実行後、packages.jsonのdependenciesにpassport-ci-oidcが書き込まれていることも確認します。

```
$ npm install passport-ci-oidc
```

次にアプリに認証機能を組み込みます。
OpenID Connectプロバイダーから払い出された情報のうち、以下のものを使います。実行前に環境変数に代入します。

- Client ID
- Client Secret
- Discovery Endpoint

加えて、Callback URL (認証後にリダイレクトされるURL)もパラメータに含めます。以下では `www.example.com` というホスト名になっていますが、アプリを実際に稼働させるときに使うホスト名に置き換えます。

``` js
const client_id = process.env.CLIENT_ID;
const client_secret = process.env.CLIENT_SECRET;
const discovery_url = process.env.DISCOVERY_ENDPOINT;
const callback_url = 'https://www.exmaple.com/api/auth/callback';

const OpenIDConnectStrategy = require('passport-ci-oidc').IDaaSOIDCStrategy;
const Strategy = new OpenIDConnectStrategy({
	discoveryURL: discovery_url,
	clientID : client_id,
	scope: 'email',
	response_type: 'code',
	clientSecret : client_secret,
	callbackURL : callback_url,
	skipUserProfile: true
	},
	(iss, sub, profile, accessToken, refreshToken, params, done) => {
		process.nextTick(() => {
			profile.accessToken = accessToken;
			profile.refreshToken = refreshToken;
			done(null, profile);
		});
	}
);
passport.use(Strategy);

app.get('/api/auth/callback', (req, res, next) => {
	const redirect_url = req.session.originalUrl;
	passport.authenticate('openidconnect', {
		successRedirect: redirect_url,
		failureRedirect: '/api/auth/failure'
	})(req, res, next);
});

app.get('/api/auth/login', (req, res) => {
	passport.authenticate('openidconnect', {})(req, res);
});

app.get('/api/auth/failure', (req, res) => {
	res.send("ログインに失敗しました");
});

const ensureAuthenticated = (req, res, next) => {
	if (!req.isAuthenticated()) {
		res.redirect('/api/auth/login');
	} else {
		next();
	};
};

app.get('/top', ensureAuthenticated, (req, res) => res.send('Hello World! User '+ req.user['id']);
```

上記のコードのポイントは、Strategyを設定するときに与えるパラメータはプロバイダーにより異なるということです。認証が通った場合や通らなかった場合の処理や、URLにアクセスされたときの認証チェックの書き方は、passportの他のStrategyを使う時と基本的に変わりません。

# 参考情報
passport-ci-oidc
[https://www.npmjs.com/package/passport-ci-oidc](https://www.npmjs.com/package/passport-ci-oidc)
[Laravel] 緯度経度情報から距離順にソートする

## 環境
Laravel 7.x
MySQL 8

## やりたいこと
緯度経度情報から店舗を近い順に並べ替えたい
精度は10mくらいでいい

## データ
DB の shops テーブルに緯度 latitude, 経度 longitude カラムがある

|id|name|latitude|longitude|
|---|---|---|---|
|1|店舗A|35.1111|137.1111|
|2|店舗B|35.2222|137.2222|
|3|店舗C|35.3333|137.3333|
|4|店舗D|35.4444|137.4444|
|...|...|...|...|

## 緯度経度から距離を出す計算式
地点P（緯度φ1，経度λ1） から 地点Q（緯度φ2，経度λ2）までの距離を x [km] とすると

``` math
x = \arccos(\cos\phi_1\cos\phi_2\cos(\lambda_1-\lambda_2) + \sin\phi_1\sin\phi_2) \times 6370
```

出典： http://www.orsj.or.jp/archive2/or60-12/or60_12_701.pdf

6370は地球の半径[km]。

## OrderByRawを使う
上記計算式を orderByRaw を使って実装する。
ソートするだけなので、定数である半径 6370 はいらない。

``` php
$latitude  = $request->get('latitude');  // 起点の緯度 queryに入っているテイ
$longitude = $request->get('longitude'); // 起点の経度 queryに入っているテイ
$shops = \App\Models\Shop::orderByRaw(
    'ACOS(COS(RADIANS('.$latitude.')) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS('.$longitude.')) 
    + SIN(RADIANS('.$latitude.')) * SIN(RADIANS(latitude)))'
  )
  ->get();
```

## 距離を値として取りたい場合
上記だとソートするだけになるが、距離も値として欲しいときはこちら。

```php
$latitude  = $request->get('latitude');  // 起点の緯度 queryに入っているテイ
$longitude = $request->get('longitude'); // 起点の経度 queryに入っているテイ
$shops = \App\Models\Shop::select('*', 
  DB::raw('6370 * ACOS(COS(RADIANS('.$latitude.')) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS('.$longitude.')) 
    + SIN(RADIANS('.$latitude.')) * SIN(RADIANS(latitude))) as distance'))
  ->orderBy('distance')
  ->get();
```
Lightning Web Componentのjs-metaファイルのtargetsタグについてハマった

# 概要
Lightning Web Component内のコンポーネント名.js-meta.xmlと言うファイルのデプロイ先を指定するtargetsタグでエラーが出たのでメモ

## エラー
今回のエラーはlightningCommunityにコンポーネントをデプロイしたい場合

```powershell
lightningCommunity_Page is not a valid TARGETS
```

##　エラー対象のtargets設定
```xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightningCommunity_Page</target>
    </targets>
</LightningComponentBundle>
```

## 正しいtargets設定

```xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightningCommunity__Page</target>
    </targets>
</LightningComponentBundle>
```

## まとめ
アンダーバーが2つ必要
AWS SAM CLIによるサーバレス環境構築

#はじめに#
前回（[エキサイトの開発現場でAWSサーバレス導入事例](https://qiita.com/h-sakamoto/items/9db438ff875f84e3be9b)）を紹介しました。今回は、SAM CLIで構築手順を紹介したいと思います。

#前提#
今回はOSX環境で直接にコマンドを叩いて試しますが、次回はDocker化します。

まず、Pythonがインストールされている確認

```
$ python --version
Python 3.8.3
```

Python 3.8.3が入った

#準備#
###AWS SAM CLIインストール###
以下のコマンドでインストールします

```
$ pip3 install aws-sam-cli
```
sam cliが入っていること確認

```
$ sam --version
SAM CLI, version 1.7.0
```
SAM CLIがインストールされました。

###AWS認証の準備###
- AMIユーザーを作成
[AWSの公式ドキュメント](https://docs.aws.amazon.com/ja_jp/powershell/latest/userguide/pstools-appendix-sign-up.html)のようにIAMユーザー作成を実施、アクセスキーIDとシークレットアクセスキーをメモしておいてください。

- AMIユーザーに必要なポリシー追加
ポリシー管理まわり複雑化したくないので、全てFullAccess権限をアタッチします。

|No.|ポリシー名|
|:--|:--|
|1|IAMFullAccess|
|2|AmazonS3FullAccess|
|3|AWSLambdaFullAccess|
|4|AWSCloudFormationFullAccess|
|5|AmazonAPIGatewayAdministrator|

厳密に制限したい場合は、[SAMの公式ドキュメント](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-template-list.html)をご参考ください。

- AWSプロファイル登録

```
$ aws configure --profile sam-deploy
以下の情報入力
<アクセスキー ID>
<シークレットアクセスキー>
ap-northeast-1
json
```
複数のサービス運用の方は、--profileオプションを付けてください。

- リリースステージ用のS3バケット作成  
AWSコンソールにログイン、S3バケット（例：excite-api-lambda-deploy-bucket）を作成します。
Infrastructure as Codeによるインフラ構築の自動化を実現したい場合は、別のプロジェクトでCloudformationもしくはTerraformでS3バケット作成の手段もあります。

#構築#
###アプリケーションのひな形生成###

```
$ sam init \
    --runtime python3.8 \
    --name excite-lambda-deploy\
    --app-template hello-world
```
excite-lambda-deployプロジェクトが作成されました。

自動生成されたプロジェクト構成が以下のようになります。

```
excite-lambda-deploy
├── README.md
├── __init__.py
├── events
│   └── event.json
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── requirements.txt
├── template.yaml
└── tests
    ├── __init__.py
    └── unit
        ├── __init__.py
        └── test_handler.py

4 directories, 10 files
```
###SAMビルド###

```
$ sam build
```
実行すると、.aws-sam/ 以下にいろいろと作成されています。

###AWSへデプロイ###

```
$ sam deploy \
   --profile sam-deploy \
    --template-file template.yaml \
    --stack-name excite-api-lambda-deploy-stack \
    --s3-bucket excite-api-lambda-deploy-bucket \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset
```
特にエラーがでなければ、これでデプロイが完了しました。

API Gatewayのアクセスポイントでアクセスしてみる（APIエンドポイントはAWSコンソール上に確認できます）

```
$ curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world"}
```
と返ってくれば成功です。

###作成したリソース削除###

```
$ aws cloudformation delete-stack  \
   --profile sam-deploy \
   --stack-name excite-api-lambda-deploy-stack
```
作成されたリソースがすべて削除されます(CloudFormation用のS3バケットはSAMの管理用なので残ります)

##最後に##
SAMで作れないAWSリソース（IAM、S3、EC2など）はCloudfrontテンプレートもしくはTerraformで構築が必要です。個人的にこちらはサーバーレスアプリケーション用のプロジェクトで、別途でインフラ構築用のプロジェクトを用意した方が良いと思います。

今回は直接にMacOSにインストールしていますが、次のDocker編は実際の開発現場に近い環境構築を紹介したいと思います。
Android Studio4.1にバージョンアップしたら、flutter doctorでDart, Flutter のプラグインがそれぞれ読み込まれない。

MacでAndroidStudio4.1にバージョンアップしたら、
DartやFlutterのプラグインをインストールしているはずなのに、flutter doctorでエラーが出る。![スクリーンショット 2020-12-03 14.14.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927271/4c8870cc-f01c-d8cb-90d8-8297eb4b76c4.png)

<code>Flutter plugin not installed; this adds Flutter specific functionality.</code>
とか、
<code>Dart plugin not installed; this adds Dart specific functionality.</code>
と出てしまう。

# 解決方法

下のコマンドを実行する。
<code>$ ln -s ~/Library/Application\ Support/Google/AndroidStudio4.1/plugins ~/Library/Application\ Support/AndroidStudio4.1
</code>

Android Studioのプラグインがインストールされる位置が、バージョン変更で変わったらしい。
flutter doctorがそれに対応し切れていない。
【Kotlin】AlertDialogを少しでも使いやすくする

#はじめに
Windowsには画面にウインドウがポップアップして「はい」や「いいえ」を問い合わせてくる**Messagebox**や**MessageDialog**があります。

Android環境でも**AlertDialog**を使えば同じようなことができます。た・だ・し、非常にソース量が増えるだけで使い勝手が良くなく、ダイアログを十数個も使うような場合には向きません。

そんな使いにくいAlertDialogを少しでも使いやすくする方法を考えていきます。

#ダイアログにOKを表示する

```MainActivity.kt
        AlertDialog.Builder(this)
            .setTitle("ここにタイトルを書く")
            .setMessage("ここに表示するメッセージを書く")
            .setPositiveButton("OK"){ dialog, which ->}
            .show()
```

これを実行するとポップアップした画面にタイトルとメッセージが表示され**OK**ボタンで閉じることが出来ます。
作業が終わった後に使用すればユーザーに処理が終わったことを知らせるのに便利です。
ただしこれだけで5行も使ってしまいました。

#ダイアログにOKとCancelを表示する
つぎに**OK**だけではなく**Cancel**も表示してみましょう

```MainActivity.kt
        AlertDialog.Builder(this)
            .setTitle("ここにタイトルを書く")
            .setMessage("ここに表示するメッセージを書く")
            .setPositiveButton("OK") { dialog, which -> }
            .setNegativeButton("Cancel") { dialog, which -> }
            .show()
```

今度はCancelも表示されたと思います。

#ダイアログのOKを押した時に用意してある処理を実行する

自作の関数として**procOk()**を用意して**OK**が押されたときに実行させたい場合は

```MainActivity.kt
        AlertDialog.Builder(this)
            .setTitle("ここにタイトルを書く")
            .setMessage("ここに表示するメッセージを書く")
            .setPositiveButton("OK") { dialog, which -> procOk()}
            .setNegativeButton("Cancel") { dialog, which -> }
            .show()
```

このように書きます。
ここまでは基本仕様です。

#AlertDialogを汎用的に使える関数を作る
何度もAlertDialogを書くのは面倒なので汎用的な関数にしてみましょう。

```MainActivity.kt
    private fun Dialog(Title :String,Message : String){
        AlertDialog.Builder(context)
            .setTitle(Title)
            .setMessage(Message)
            .setPositiveButton("OK") { dialog, which -> }
            .show()
    }
```

このように定義しておけば

```MainActivity.kt
    Dialog("ここにタイトルを書く","ここに表示するメッセージを書く")
```

毎回5行も書かないといけないのが1行で済むようになりました。
ここまでは誰でもやりそうですね。

#OKを押されたときの処理も汎用関数に渡す

先ほどの例でOKを押したときprocOk() を呼ぶようなサンプルを書きましたが、これも汎用関数として定義して、1行で呼び出せることが出来れば便利ですよね

##やりたいこと
```MainActivity.kt
    Dialog("ここにタイトルを書く","ここに表示するメッセージを書く",procOk())
    Dialog("ここにタイトルを書く","ここに表示するメッセージを書く",procNg())
```
こんな風に呼び出せる汎用関数にして見ましょう

#関数の引数で関数を渡す
日本語にするとなんだか意味不明ですが
関数の引数で数値型や文字型の他に関数を型として渡します。

```MainActivity.kt
    private fun <T>Dialog(Title :String,Message : String,func: ()->T){
        AlertDialog.Builder(context)
            .setTitle(Title)
            .setMessage(Message)
            .setPositiveButton("OK") { dialog, which -> func()
            }
            .show()
    }
```

このように定義しておけば

```MainActivity.kt
    Dialog("ここにタイトルを書く","ここに表示するメッセージを書く",{procOk()})
    Dialog("ここにタイトルを書く","ここに表示するメッセージを書く",{procNg()})
```

ダイアログに表示させるメッセージの他にOKを押されたときに実行する関数も渡すことが出来ます。

#最後に
確認する項目が多い場合には便利だと思います。

要望があれば画面切替にFragmentを利用しているのに、ダイアログの処理はMainActivityに書かないといけないことの回避策も記載したいと思います。
会社のスケジュール管理はわかりにくいって？自分で作ればいいじゃないですか！

# はじめに

当方が以前の会社でやっていた、個人的なスケジュール管理によって作業が効率化出来た話をご紹介できればと思います。

# そもそも

会社が共通で使用しているスケジュール管理システム(CyboseでもいいしLycheeでもいいし、なんならGoogleSpreadsheetでもいい)を使う上で、社員個人にとっては

・必要最低限な情報は網羅されているけど、個人的にはもっと情報が欲しい
・いつのタイミングで作業をすればいいのかわからない

と文句を言いながら会社のスケジュール管理に振り回されているときは…断言します。

**必要なぶんを自分で作ればええやん！**

# やりかた

これについては…各自で適切な(すぐにインプット・アウトプットできる)環境でやればいいです。

## スケジュール帳の作成

例として、当方がExcelでやっていた方法を伝授いたします。

1. Aから数列は余裕のある長さにしておき、各1行めにタイトルを入れます
(「大タスク名」とか「小タスク名」、「プロセス」とか入れていきます)
1. そこ以降の行は方眼を作っていきます
1. 前項で長さを添えた列の1行目に日付を入れていきます
(このとき、１シート＝１ヶ月ぶんのスケジュールを記載すると想定します）
(2行目に曜日を入れられればなおベター)
1. 表とは別の場所に、「済」「実装終了」「実装開始」「検討」など、共通の手順項目名が一列になるように記載します
(リストボックスで選択できるようにするためです)
1. 前項で指定した拡張書式を方眼に適応していきます

これでスケジュール管理システムが出来上がりました。

## スケジュール時のルール作り

あとは、記載するときにルールを適応します。

例えば、

* 開始する予定の日の列は青色を付けておく
* 終了する予定の日の列は赤色を付けておく
* 特別な予定の日の列は緑色を付けておき、メモで補足を入れておく
* 完了したタスクは、その日以降の列は黒色で塗りつぶす
* 翌月分を記載する際、黒で塗りつぶした行は省略する、それ以外は引き続き使用するために転載する

といった感じで、どの作業をどのタイミングで行えばいいのかを逐次確認できるようにしています。

このことを、Excelのスケジュール管理に影響が出ない場所（表以外の場所にテキストボックスを置いたり、新しくシートを作って「凡例」という名前にしたり、ご自由に）にメモしておけばモアベターです。

# 要視するべき視点

個人用スケジュールを作るに当たって特に重要な視点は、

## 会社共通の方式にすぐに適応できる書式にしておく

ことです。例えば、チームの進捗会議や、部内の報告会で必要な情報を記載するときに、それに見合わない書式だと報告する際に頭をひねることになります。
できるかぎりストレスをかけないような書式を心がけてください。

## 手早く作る

なぜ、私がExcelを使ったのか…それは「**すぐ作れそうだったから**」。
翌月のシートを作るのも、雛形さえあればかんたんです。
何ヶ月も駆けてシステム設計して実装して…という世界だったら窓の外にぶん投げちゃいましょう。もちろん、1日で仕上げられるというなら話は別です。がんがん作ってアウトプットしたらいいと思います！

# さいごに

元々は、スケジュールをどうやって使いこなしたら自分がチームのために動けるんだろうという思いから思い立って実施したものです。
この方式で、チームメンバーからスケジュールの点で変化があった際なども素早く対応できるようになり、コミニュケーションのロスが少なくなりました。
チケットを更新したりクローズしたときのエビデンスにもなり、現状確認や進捗報告の効率化という点で非常に助かりました。
みなさんも、スケジュール管理にストレスのないワークライフを！
Progate SQL学習

<h1>SQL</h1>
ProgateのSQLⅠ～Ⅳを約3時間ほどで学習しました。この分野ではSQLをどのようなものか、どのように使うのか学びました。
<h3>データベースとは</h3>
**データベース**とは、テキストや数値などのデータを保存するためのツールです。データベースは、表でデータを管理おり、表のことを**テーブル**と呼びます。また、縦の列のことを**カラム**、横の行のことを**レコード**と呼びます。データベースでは、必要に応じて複数のテーブルを作成することが可能です。

データベースからデータを取得するためにデータベースに送る命令を**クエリ**と言います。また、クエリを書くための言語を**SQL**と言います。

<h1>SQLの基礎構文</h1>
データベースから、データを取得するためには**SELECT**を用います。このSELECTを用いて、「どのカラムのデータを取得するか」を選びます。また、**FROM**を用いて、SELECTで選んだカラムが「どのテーブルのカラムか」を指定する必要があります。最後にセミコロン(;)を加えます。

```sql
SELECT ○○(どのカルムのデータを？)
FROM □□(どのテーブルから？);
```

特定のデータを取得するためには、「どこの」という意味を持つ「WHERE」を用います。WHEREの条件には
**=**や**<**,**>**,**<=**などの大小比較の記号を用います。

```sql
WHERE category = "雑貨";
WHERE price >= 1000;
```
「ある文字を含むデータ」を取得したい場合は、**LIKE演算子**を用います。

```sql
WHERE name LIKE "%イチゴ%";
```
「〇〇を含まないデータ」や「〇〇に一致しないデータ」のような条件でデータを取得したい場合は「否定」を意味する**NOT演算子**を用います。

```sql
WHERE NOT price >= 1000;
```
NULLのデータを取得するためには「〜がNULLである」という意味になる、**IS NULL**を用います。

```sql
WHERE price IS NULL;
```

データを並び替えるためには、「〜順に並べる」という意味の**ORDER BY**を用います。並べ方を指定するとき、「昇順」は**ASC**、「降順」は**DESC**と指定します。

```sql
ORDER BY price DESC;
```

「最大で何件取得するか」を指定するためには、「制限する」という意味の**LIMIT**を用います。

```sql
LIMIT 5;
```

<h1>最後に</h1>
洗練さんでインターンの課題(Progate 学習コース　SQLⅠ～Ⅳ)です。
[Progate 学習コース　SQL](https://prog-8.com/languages/sql)


最後に
現在ここでインターンしています。
まだまだ駆け出しですが頑張ります！やる気は人一倍です！
https://senren.work/
redux-observable全体でエラーハンドリングする

# はじめに

redux-observableでエラーをthrowしてくれるライブラリを扱うこともよくあります。
ただ、それぞれのEpicに同じようなcatchErrorを書いていくのは面倒。
Epic全体でエラーハンドリングできないものか:thinking:

# 解決策

combineEpicsをラップします:hugging:

```typescript
const rootEpic = (
  action$: ActionsObservable<Action<unknown>>,
  store: StateObservable<void>,
  dependencies: unknown
) =>
  combineEpics(
    // あなたのEpic
  )(action$, store, dependencies).pipe(
    catchError((error, caught) =>
      merge(of(yourActions.handleError(error.message)), caught)
    ),
    mergeMap(action => of(action))
  );
```

# 参考にした記事

[How to add a global error handler for all redux-observable epics?](https://stackoverflow.com/questions/39499565/how-to-add-a-global-error-handler-for-all-redux-observable-epics)

[RFC: default error handling of Epics](https://github.com/redux-observable/redux-observable/issues/94)
platform.js のparse()に"てきとー"なUserAgentを入れたときの戻り値


```
// 本来はUserAgentを入れるとこに'てきとー'をいれてみる
console.log(platform.parse("てきとー"));
 
// 結果
{
	"description": "てきとー",
	"layout": null,
	"manufacturer": null,
	"name": null,
	"prerelease": null,
	"product": null,
	"ua": "てきとー",
	"version": null,
	"os": {
		"architecture": null,
		"family": null,
		"version": null
	}
}
```
platform.js ver1.3.6
https://github.com/bestiejs/platform.js/
[Rails] has_many関連を操作するためのフォームで collection_check_box が使えないときに _destroy 属性を使ってチェックボックスを作る時にはvalueを反転させてやると良い

Railsで`accepts_nested_attributes :hoge, allow_destroy: true`な`has_many`関連を操作したい時に`collection_check_box`を使うことがよくありますが、諸事情でこれが使えない時に、`ff.check_box :_destroy, {}, '0', '1'`と`_destroy`属性のチェックボックスを`value`の値を反転させて作ってやるとよい。
思いつけば単純なのですがハマって時間かかってしまったのでメモ。