OmniAICreator/Qiita-1.07M huggingface dataset:
CSSの記述が間違っていてエラーが出た話

## 環境
macOS Catalina 10.15.7
Ruby on Rails 6.0.0
RSpec 4.0.1
pry rails 0.3.9

## エラー内容
RSpecで `visit root_path` を実行したタイミングでエラーが発生した。


```terminal:console
Failure/Error: <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     
     ActionView::Template::Error:
       Invalid CSS after "...kground-color: ": expected expression (e.g. 1px, bold), was "##253141;"
     
     
     
     # (sass):8
     # ./app/views/layouts/application.html.erb:8:in `_app_views_layouts_application_html_erb__1634657128219108166_70256618570500'
     # ------------------
     # --- Caused by: ---
     # Sass::SyntaxError:
     #   Invalid CSS after "...kground-color: ": expected expression (e.g. 1px, bold), was "##253141;"
     #   (sass):8

```
デフォルトで `app/views/layouts/application.html.erb` に記述されている、外部スタイルシートを指定するリンクタグを生成するメソッドを読み込んだタイミングでエラーが発生している。

## 対処
エラー内容をみると、Invalid CSSとなっている。`##253141;`というtypoがあるようなので、VSCodeの文字列検索で探してみる。

```css:messages.css
.side-bar {
  width: 300px;
  height: 100vh;
  background-color: ##253141;
}
```
 あった。
 #を一つ消し、`visit root_path`が正しく動作することを確認できた。
今回、VSCodeの検索機能を初めて使用したが、めちゃくちゃ便利なので、今後も使っていきたい。
Ruby on railsとLalavelどっちが良い？

<h1>技術選定の仕方</h1>
・自分のやりたい事が実現しやすい
・情報量が多い

プログラミングはあくまでも手段でしかなく、プロダクトの価値を最大化させることこそが目的である。またプログラミング言語は、基礎文法は少し変わるぐらいで大した差はない。言語に縛られるよりも、自分が言語に合わせて勉強していくほうが、プロダクトの価値も開発効率も上がる。

<h1>Ruby on railsを選びました</h1>
①scaffoldが便利
MVCの作成はrouteの設定までいい感じに自動で生成してくれる。

②情報量が多い！
ruby自体が日本発の言語ということもあり、qiitaの記事の数をはじめ日本語の説明の記事がlalavelよりも多い。

③コミュニティー内に参考にできるソースコードがある
身近にコードについて質問でき参考にできるコードがあるのは、めっちゃ楽。

>Rails: ある程度の規模まではレールに乗ってサクサク作れるが、アプリケーションが成熟してきて「規約」にはないことをやりたくなってくると、途端に求められる技術力や難易度が跳ね上がる。
Laravel: アプリケーションの雛形はあるものの、どのクラスに何を担わせるかなど、設計については Rails 以上に早い段階で意識する必要がある。その設計さえイケていれば、だいたいのことはしっかり書ける。
Rails 歴5年の僕が Laravel で開発するようになって思ったこと。
https://note.com/kurashicom_tech/n/n32ab25910783

<h1>結論</h1>
僕のような初学者には、railsをおすすめします。railsのレールに乗りながら、まずはMVCの基礎を自分にインプットしていく。その後、lalalvelに挑戦！で良いかなと思う。
どちらの言語も実行コマンドは似ているし、Railsはgem、Laravelはcomposerを使えば各種プラグインも簡単に導入できるので、あまり差はないと感じます。
最後まで読んでいただきありがとうございます。
WEBアプリケーションの脆弱性

#▶はじめに
今回は「WEBアプリケーションの脆弱性について」自身の復習もかねてまとめてみました。

#▶WEBアプリケーションへの攻撃
Webアプリケーションへの攻撃は『**HTTPリクエストメッセージに攻撃コードを載せて**』行われます。

クエリーやフォーム、HTTPヘッダー、Cookie等を経由して送り込まれ、Webアプリケーションに脆弱性があった場合には情報が盗まれたり、権限が取られたりすることがあります。

###《WEBアプリケーションへの攻撃パターン》

●能動的攻撃
●受動的攻撃

#▶能動的攻撃	
能動的攻撃とは『**攻撃者が直接Webアプリケーションに対してアクセスをし、攻撃コードを送るタイプの攻撃**』です。

能動的攻撃の代表的な攻撃には『**SQLインジェクション**』や『**コマンドインジェクション**』等があります。

#▶受動的攻撃
受動的攻撃とは『**罠を利用してユーザーに攻撃コードを実行させる攻撃**』です。
攻撃者はWebアプリケーションにアクセスして攻撃を行います。

受動的攻撃の代表的な攻撃には『**クロスサイトスクリプティング**』や『**クロスサイトリクエストフォージェリ**』等があります。

###✖罠タイプ型は2つ✖
（攻撃用の罠となるスクリプトをどこに配置するかによって型が異なる）

●反射型・・・攻撃用のスクリプトが攻撃対象のWEBページとは別のところにある場合（罠サイトやメールに記載）
●持続型・・・攻撃用のスクリプトが攻撃対象のWEBサイトのデーターベースなどに保存される場合

受動的攻撃を利用すると『イントラネット』などの攻撃者が直接アクセスすることができないネットワークに対しての攻撃を行うことも可能！

攻撃者はイントラネット向けに内部のIPアドレス等を攻撃コードとして罠を用意し、それがユーザーがアクセス可能なネットワークであれば、イントラネットに対してでも『受動的攻撃』を行うことが可能になります。

※イントラネット・・・『内部ネットワーク』インターネットに対して、企業や研究所など内部ネットワークのことを指す。

#▶インジェクション
Webアプリケーションでは処理が終わった後に、様々なシステムに『出力処理』を行うことがあります。
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685823/4b406ef0-565a-b44d-48e1-721cf705fb86.png)
👆
この出力先に共通するのは、何らかの文字列のデータを出力し、出力先に送っているというところです。（それぞれのインターフェースに文字列を送っている）

| 操作    |種類 |
|:-----------------|:------------------|
| データーベース処理    |-SQLインジェクション |
| OSコマンド処理 |-コマンドインジェクション |  
| メール送信 | -メールヘッダーインジェクション |  
| HTTPメッセージ表示  | -クロスサイトスクリプティング |  
|                | -HTTPヘッダーインジェクション |  
これらの出力に起因する脆弱性がインジェクションに分類されます。

#▶SQLインジェクション
データーベースを利用しているWebアプリケーションで、**”SQLの呼び出し方に不備がある場合”**発生する脆弱性！

###《SQLインジェクションにより受ける可能性のある影響》

●データーベース内のデータの不正な閲覧や改ざん
●認証の回避
●データーベースサーバーを経由したプログラムの実行等

#▶コマンドインジェクション
OSのシェルで動作するコマンドを不正に実行できてしまう脆弱性！
（OSコマンドインジェクションとも呼ばれる）

####《コマンドインジェクションによって受ける可能性がある影響》

●WEBサーバー内部のファイルが実行されたり読みだされたりする
●管理者権限が奪われ、別サーバーへの攻撃の踏み台として利用される

#▶メールヘッダーインジェクション

メールメッセージのヘッダー部分に攻撃者が**”改行コード等を挿入することで、任意のヘッダーフィールドやボディを追加する”**ことができる脆弱性！

####《メールヘッダーインジェクションによって受ける可能性がある影響》

●宛先（To）や件名（Subject）などを書き換えられたメールが送信される
●スパムや悪意のある本文を書いたメールが送信される
●悪意のあるファイルを添付ファイルとして付けてメールが送信される
※攻撃手法はHTTPヘッダーインジェクションとほぼ同様。


#▶クロスサイトスクリプティング（XSS）

WEBサイトのユーザーのブラウザ上で、HTMLタグやJavaScriptなどが動いてしまう脆弱性！

外部からの入力等に応じてHTMLやJavaScriptを自動に生成している箇所で、生成する際に適切にHTMLのエスケープ処理（文字列の処理）ができていない場合などに発生します。（攻撃には被害者の介在が必要な受動的攻撃に分類される）


#####《クロスサイトスクリプティング（XSS）によって受ける可能性がある影響》

●脆弱性のあるWEBサイトのユーザーのCookieが盗まれることで、そのユーザーになりすまされる
●不正に追加されたHTMLによって偽の情報や偽のフォーマット等が表示され、ユーザーが騙される
●悪意のあるJavaScriptが実行されることでマルウェアに感染する

#▶HTTPヘッダーインジェクション

レスポンスヘッダーフィールドに攻撃者が改行コードなどを挿入することで『任意のレスポンスヘッダーフィールド』や『ボディ』を追加することができる脆弱性！
※攻撃には被害者の介在が必要な受動的攻撃に分類されます。

####《HTTPヘッダーインジェクションによって受ける可能性がある影響》

●任意のURLにリダイレクトされることで、悪意のあるWEBサイトに誘導される
●任意のCookieが生成されることで、セッションフィクセイション攻撃に利用される
●任意のHTTPボディが生成されることで、WEBページに表示される内容が改変される

#参考文献
書籍：Webセキュリティ担当者のための脆弱性診断スタートガイド
　　　上野宣が教える新しい情報漏えいを防ぐ技術　第2版
著者：上野　宣
【GA4対応】Google Tag Managerでフォームのコンバージョンイベント取得（MW WP Formの例）

Google analyticsが新しくアップデートされ、UIから何から変わりました。
正式には、Google Analytics 4（GA4）という名称とのこと。
Google Tag Manager（GTM）でも、これまでのアナリティクスようのタグとは別に、GA4用のタグが用意されています。

##前提条件
GA4基準に、フォームのコンバージョンイベントをタグマネを使って取得する方法をまとめます。
ページのURLが変わらず、フォームのClassでコンバージョンを取得するパターンを想定し、
WordpressのプラグインMW WP Formでページ遷移しないフォームを例にしています。

また、すでにGA4のAnaryticsのタグ設定は、GTMで設定されている想定です。
![スクリーンショット 2020-11-25 10.59.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/94622440-f222-b36a-fdf2-4a812588fd3f.png)

##変数の準備
MW WP Formの場合、確認画面、完了画面において、フォームにクラスが追加されます。
そのため、現在どのクラスが追加されているかを取得するための変数を作成します。

```javascript
function(){
  //IDを指定して対象のフォームを設定
  //mw_wp_form_mw-wp-form-10の部分は対象のフォームのIDに置き換える
  var element = document.getElementById('mw_wp_form_mw-wp-form-10');
  if( element.classList.contains('mw_wp_form_confirm') == true ){
    return 'confirm';//確認画面の場合、confirmを返す
  } else if ( element.classList.contains('mw_wp_form_complete') == true ){
    return 'complete';//完了画面の場合、completeを返す
  } else {
    return 'input';//それ以外は、inputを返す
  }
}
```

###実際の例
![スクリーンショット 2020-11-25 9.36.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/9b478778-8534-323d-7bc2-488d3107fdbe.png)

この変数は、確認画面の場合confirmを、完了画面の場合completeを、それ以外はinputを返します。

##タグとトリガーの作成
変数が準備できたらタグを作成していきます。
まずは確認画面のタグから作成します。
新しくタグを作成し、タグの種類として「Google アナリティクス: GA4 イベント」を選択します。

設定タグに対象のGA4のアナリティクスを設定、イベント名に任意の名前を入力します。
このイベント名は、Analyticsで表示されるイベント名となります。

続いて配信トリガーをクリックし、トリガーを追加します。
トリガーのタイプをページビュー-DOM ready、
トリガーの発生場所を一部のDOM Readyイベントを選択、
そして条件に、先ほど作成した変数を追加、等しいを選び、confirmを入力します。

![スクリーンショット 2020-11-25 11.12.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/5b23fbf5-c43a-c6cc-89c7-675fe5c0dfa8.png)


これで確認画面は完了です。トリガー、タグを保存して閉じます。

![スクリーンショット 2020-11-25 11.12.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/0fb5fd79-6cfc-1114-1fc3-1ea76529305f.png)


同様に、完了画面も設定します。
変数は共通のものを使いますが、タグとトリガーは新しく作る必要があります。
（先に作った確認画面のタグ・トリガーをコピーして作ると楽です）

トリガーの条件は、completeと入力します。

![スクリーンショット 2020-11-25 11.08.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/145700d2-c863-2d39-403d-439ae826df70.png)

タグのイベント名も、わかりやすいものに変えます。

![スクリーンショット 2020-11-25 11.01.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/d5803d0d-e94e-7458-6ef1-40321e723f2a.png)

GTMのプレビューでサイトを開き、タグの発火を確認したら公開します。
公開後、フォームを操作してテストし、Analyticsでイベントが表示されるのが確認できれば成功です！
![スクリーンショット 2020-11-25 9.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/14ee106c-004f-aa36-b250-098dbc03592e.png)

##Analyticsの設定
あとは後日、Analytics側でイベントをコンバージョンとしてマークしておけば、効果測定も可能です。
![スクリーンショット 2020-11-25 11.20.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229958/861bd47e-a8b9-e1b2-fa3b-68f4544e5b1d.png)
Athlon1600/php-proxy-app

PHPで動作するプロキシは Glype や PHPProxy といったのがありましたが、更新が滞っていたので代わりを発見しました。

## インストール

* https://www.php-proxy.com/
* https://github.com/Athlon1600/php-proxy-app

```sh
wget "https://www.php-proxy.com/download/php-proxy.zip"

unzip php-proxy.zip
cd php-proxy
php -S 0.0.0.0:8000
```

![aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/be41e66f-429b-6f5c-6fef-2c470fd630bb.png)


## 設定

* config.php

```diff
- $config['app_key'] = '';
+ $config['app_key'] = 'xxxxxx';
```

### GETも受け取るようにする

* `http://localhost:8000/?url=http://google.co.jp`のようにリンクを書けるように。

```diff:index.php
- if (isset($_POST['url'])) {
-     $url = $_POST['url'];
+ if (isset($_REQUEST['url'])) {
+     $url = $_REQUEST['url'];
```
Growiの編集時に自動でslack通知ボックスにチェックを入れる

# 前提
・SlackとGrowiの連携はすませてある。
・使用者が通知ボックスにチェックを入れる習慣がないが、一方でページの編集・作製は通知したい。

# すでにある取り組み
https://qiita.com/ymm1x/items/15278f6ef1794b718955
https://qiita.com/nao-guitarist/items/82ed2ed7cb2e9eacd08a

# なぜ改めて記事を書いた？
* Growiの仕様変更により要素の指定先が変わっている。（これだけなら編集リクエストすれば良いのだけど）
* Qiitaに記事を初めて書いてみたかった。（そのついでにという感じ）
* Growiの記事もっと欲しかった。（ささやかなあがき）

# 結論
管理者アカウントでログイン後、カスタムスリプト内に以下を書く。

```JavaScript:admin/customize
function slackPostTrue() {
  document.querySelector('div label input').closest('label').click()
  document.querySelector('div label input').checked = true
}

window.addEventListener('keypress', (e) => {
  if( location.hash == '#edit' && document.querySelector('div label input').checked != true ) {
    slackPostTrue()
  }
})
```

[@nao-guitaristさんの記事](https://qiita.com/nao-guitarist/items/82ed2ed7cb2e9eacd08a
) での指定要素を'div label input'に替えただけ。
[ymm1xさんの記事](https://qiita.com/ymm1x/items/15278f6ef1794b718955
) でも同様に、かつての要素位置<code>'#save-page-controls input[type=checkbox]'</code>を変更すればOK.
.NET Core 3.1 の Windows Forms で PerMonitorV2 動かしてみた

[先日やった .NET Framework 4.7.2 + Windows Forms の PerMonitorV2 での動作確認](https://qiita.com/okazuki/items/4a1e44d372dc8e854775) ですが LTS 版の .NET Core 3.1 でも試してみました。

ちなみに元記事に追記していますが、ListBox の変な動きは .NET Framework 4.8 にしたらなおってました。めでたしめでたし。

## やってみよう

.NET Core 3.1 では、.NET Framework と違って Main メソッドで `Application.Run(new Form1());` より前に `Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);` を呼ぶことで PerMonitorV2 になるらしいです。

[WinForms の高 DPI](https://docs.microsoft.com/ja-jp/dotnet/core/whats-new/dotnet-core-3-0#winforms-high-dpi)

ということでフォームの AutoScaleMode を DPI にして ListBox と DataGridView を置いて試してみました。

100%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/888ac2e9-bd8a-890e-236c-26969401012f.png)

150%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/37f061f1-2627-cb90-7805-38414b9eb821.png)

100%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/256ca730-f572-0475-2fa0-7eb48ee9f7ff.png)

ListBox の愉快な症状はおきなかったですが、DataGridView の CheckBox は 150% に持って行っても小さいままでした。
ここら辺は自前でどうにか頑張る（頑張り方は自分は知らない…）しかないのかなぁ？

## ここまでのまとめ

.NET Framework 4.8 と .NET Core 3.1 では ListBox と DataGridView を見る限りは動きはそんなに変わってないように見えるので、あとは、DataGridView のようにそのまま使っただけではちゃんと動かないコントロールの対応方法などを確認しないといけないかも。
ネットワーク　OSI参照モデルの表

# OSI参照モデル

通信機能のモデル。
国際標準化機構(IOS)が作っています。
通信機能をどんな仕組みにするのかを整理した共通ルールのひとつ。

No|層|説明
---|---|---
第1層|物理層|ケーブルなどの物理的な繋がりに関する規則
第2層|データリンク層|直近の機器との通信する際の規則
第3層|ネットワーク層|目的の相手と通信する際の規則
第4層|トランスポート層|通信における信頼性確保のための規則
第5層|セッション層|通信時のセッションに関する規則
第6層|プレゼンテーション層|通信時のデータ変換形式の規則
第7層|アプリケーション層|通信時のソフトとの窓口に関する規則

![スクリーンショット 2020-11-25 10.41.32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169789/a365fde5-658d-9dc4-e5a8-5c737c68f399.jpeg)

## ping

TCP/IPのネットワーク層でICMPを使用したネットワーク通信の診断プログラムです。

## ICMP

ICMP ( Internet Control Message Protocol ) は、IPプロトコルの「エラー通知」や「制御メッセージ」
を転送するためのプロトコルです。

## DHCP

DHCP ( Dynamic Host Configuration Protocol ) は、ネットワーク接続するのに必要なIPアドレスなどの情報を自動的に割り当てるアプリケーション層プロトコルです。

IPv4で主に使用されます。
IPv6では、自動的に複数のIPアドレスを設定する機能がありますが、場合によってはDHCPを使用することもあります。
Apple Silicon に python3 用google-cloud-bigquery ライブラリをインストール

Apple Silicon python3 google-cloud-bigquery インストール作業メモ 2020/11/25

python3はmacOS Big Sur にバンドルのものを使います。
もちろんこれはarm64対応(x86にも対応のUniversal)です。
$ which python3
/usr/bin/python3
$ lipo -archs /usr/bin/python3
x86_64 arm64e

pip3は直接呼び出すとwarning出るので回避
alias pip3='/usr/bin/python3 -m pip'

1, ターミナルアプリを Rosetta(x86互換)モードで開く
[アプリケーション]-[ユーティリティ]-[ターミナル]を右クリック
[一般情報]-[Rosettaを使用して開く]にチェック
あとは普通にターミナルを起動

2, grpcインストール
$ pip3 install grpcio

3, ターミナルアプリを標準(arm64)モードに戻す

4, google-cloud-bigqueryインストール
$ pip3 install google-cloud-bigquery

以上

注：コンパイラがOSバージョンについてのエラーを吐くときは
以下の環境変数をセットしてください。
SYSTEM_VERSION_COMPAT=1

いずれこれは不要になるでしょうからその時は削除してください。
とにかくGolangでAvroを使わせろ

#概要
Apache Avroにはデータ・スキーマを用いて永続化や通信を行うデータを圧縮する為の仕様「A compact, fast, binary data format.(コンパクトで高速なバイナリ形式データ)」があります。
本記事ではAvroの詳細まで言及しませんが、この仕様をGolangで実装して圧縮されたデータを実感してみたいと思います。

#データ圧縮の準備
###Avroスキーマ
Avroバイナリデータに圧縮するには、予めデータ構造のスキーマ定義を作成する必要があります。
まずは２つの項目を持つ簡単なスキーマを定義します。
(後ほどGolangのソースコード内でstringデータとして使用します)

```json
{
  "namespace": "TestSchema",
  "type": "record",
  "name": "TestData",
  "fields" : [
    { "name" : "id", "type" : "int" }, { "name" : "value", "type" : "string" }
  ]
}
```
###圧縮前のデータ(JSON)
スキーマにはint型の"id"と言う名前の項目とstring型の"value"と言う２つの項目が定義されています。
この定義に沿った以下のJSONデータを作成します。

```json
{"id":10001,"value":"test_value"}
```

#データ圧縮ロジック
###Goライブラリ
以下のコマンドを実行してライブラリを取得します。

```go
go get "github.com/linkedin/goavro"
```
##シリアライズ処理手順
以下の手順で実行します。

```Go
// 1.JSON文字列をGolangのプリミティブ型のデータへ変換
// 1-1.スキーマを設定したCodecを生成
codec, _ := goavro.NewCodec(`
  {
    "namespace": "TestSchema",
    "type": "record",
    "name": "TestData",
    "fields" : [
      { "name" : "id", "type" : "int" }, { "name" : "value", "type" : "string" }
    ]
  }`)

// 1-2.JSON文字列をGoデータへ変換
textual := []byte(`{"id":10001,"value":"test_value"}`)
native, _, err := codec.NativeFromTextual(textual) // nativeはmap[string]interface{}型
if err != nil {
  panic(err)
}
log.Printf("textual length:[%d]\n", len(textual))

// 2.GoデータをAvroバイナリへシリアライズ
binary, err := codec.BinaryFromNative(nil, native) // binaryは[]byte型
if err != nil {
  panic(err)
}
log.Printf("binary length:[%d]\n", len(binary))
```

###処理結果
元のJSON文字列33バイトから、バイナリデータ変換後は14バイトまで圧縮されています。

```
textual length:[33]
binary length:[14]
```

##デシリアライズ処理手順
以下の手順で実行します。
Codecはシリアライズと同じものを使用できます。

```Go
// 3.AvroバイナリデータをGoデータへデシリアライズ
native, _, err := codec.NativeFromBinary(binary)
if err != nil {
  panic(err)
}
log.Printf("Deserialized:%v\n", native)

// 4.JSON文字列に戻すことも可能
textual, err := codec.TextualFromNative(nil, native)
if err != nil {
  panic(err)
}
log.Printf("JSON string :%v\n", string(textual))

```
###処理結果
バイナリから復元されたデータは**map[string]interface{}型**に変換されます。

```
Deserialized:map[id:10001 value:test_value]
JSON string :{"value":"test_value","id":10001}
```

###どの辺がポイント？
・データ構造の情報を持たない
　シリアライズにもデシリアライズにもスキーマ定義が必要で、その管理も必要になりますが、スキーマに書かれている情報を持つ必要が無いのでデータは小さくなります。
　永続化にも通信にも有用です。
***

取り急ぎGolangでAvroのデータを扱いたい時は上記ソースコードをコピペして、スキーマ定義とJSON文字列を適切な値へ置換してください。(エラー処理の実装も忘れずに)

#Appendix
*[Apache Avro公式ページ](https://avro.apache.org/)
*[linkedin/goavro(Github)](https://github.com/linkedin/goavro)
はじめてのコード整理チェックリスト

## はじめに

コードレビューをもらう前などにチェックしているリストです。
誰でもできます。
気づいたことがあれば更新する予定です。


## 超基礎編
#### ・ selfを付ける
#### ・空行、空白が統一されているか
#### ・メソッド名や変数名がキャメルケースになっているか

```
// NG例
func appendname() {
    let Name = "なまえ"
}

// OK例
func appendName() {
    let name = "なまえ"
}
```
#### ・不要な変数、処理、コメントがないか</B>
  * 定義したけど使わなかった変数
  * 実は処理が通っていないメソッド
  * メモ程度で書いていたコメントなど...


## 基礎編

#### ・マークコメントを付ける

```
例)
  //MARK: - Action   　　　　//ここからはActionの処理を実装しますという意味

    @IBAction func numButton(_ sender: UIButton) {
        guard let num = numLabel.text else {
            return
        }
        guard let senderdNum = sender.titleLabel?.text else {
            return
        }
        numLabel.text = num + senderdNum
    }
```

|  マークコメントを付けると、選択したマークコメントに飛べます |
| ---- |
| ![MARC.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692883/8411c180-589b-6dc0-6055-2c3de1ea8040.gif)
 |

#### ・ドックコメントを付ける

```
    /// ボタンを押下した時の処理　　　　　　　//メソッドなどの処理説明を書く
    /// - Parameter sender: UIButton　　　　　
    @IBAction func numButton(_ sender: UIButton) {
        
        guard let num = numLabel.text else {
            return
        }
        guard let senderdNum = sender.titleLabel?.text else {
            return
        }
        numLabel.text = num + senderdNum
    }
```
ショートカットキー

|  ドッグコメント  |
| ---- |
|  command⌘ + option + /  |


#### ・アクセス修飾子を付ける
[知っているようで知らないSwift5のアクセス修飾子] (https://qiita.com/mototaji/items/d1ae68457a118df71458)

#### ・メソッドの命名をわかりやすくする(どんな処理をしているのか)
[うまくメソッド名を付けるための参考情報] (https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)






## 参考
[知っているようで知らないSwift5のアクセス修飾子] (https://qiita.com/mototaji/items/d1ae68457a118df71458)
[うまくメソッド名を付けるための参考情報] (https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)
Cloud9でThis code could not be beautifiedといわれて驚いた

# 事象 : Cloud9を開いたら「This code could not be beautified」とダイアログが出た
画面を開いて早々に突然ディスられた、と思って驚いた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/0a68ce68-12cf-5475-6c15-30a5411431b2.png)

## 原因 : コードフォーマッターが動いただけ
参考 : [Code Formatter · Cloud9 SDK](https://cloud9-sdk.readme.io/docs/code-formatter)

コードフォーマッターのショートカットはWindowsで`Ctrl + Shift + B`。
Chromeのお気に入りを選択するショートカットと`Alt + Shift + B`。
手癖が悪すぎて多分押してしまった。

そしてコードフォーマッターの設定はしていない状態なので「"Python" is not supported yet」といわれたのであろう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/b951cc0f-74dd-9273-8478-45c23d1d015f.png)

### 対応 : ディスっているわけではないので悲しまない
Cloud9のコードフォーマッター機能を知る機会を頂けたと思って精進する。

- 参考
    - [AWS Cloud9 Integrated Development Environment (IDE) でプロジェクト設定を操作する - AWS Cloud9](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/settings-project.html#settings-project-change-code-formatters)
    - [AWS Cloud9でyapfを使ってPythonコードを自動整形する - Qiita](https://qiita.com/sho-hitomi/items/cbcaa5cffb65c98fb5d7)
historyを完全に消化

# 概要
historyは「history -c」で削除できる。しかし、historyはメモリにも保管されていて、ログアウトした時にメモリから復元されてしまう。その結果、再びログインするとhistoryが再び表示される。

# コマンドライン
次のスクリプトを実行すると完全に削除される。
```
cat /dev/null > ~/.bash_history && history -c && exit
```
# Ansible
ディレクトリ構成
```
~/ansible
  |- server
     |- erase_history.yml
~/scripts
  |- server
     |- erase_script.sh
```

## ansible-playbook
erase_history.yml
```
---
- name: check firewall setting
  hosts: "{{ host | default('network') }}"
  gather_facts: no

  tasks:
    - name: erase history
      shell:  "cat /dev/null > ~/.bash_history && history -c && exit"
      args:
        executable: /bin/bash
```

## bashスクリプト
erase_history.sh
```
#!/bin/bash

HOST=""

usage() {
  echo "Usage: erase_history.sh [-n ホスト名] [-h ヘルプ]\nhistoryを初期化する" 1>&2
}

exit_abnormal() {
  usage
  exit 1
}

call_ansible_script() {
  cd ~/ansible/server/
  CMD="ansible-playbook erase_history.yml --ask-vault-pass"
  ARG=""
  if [ ! -z "$HOST" ]; then
    ARG="host=$HOST"
  fi
  ARG="$(echo -e "${ARG}" | sed -e 's/^[[:space:]]*//')"
  if [ ! -z "$ARG" ]; then
    CMD+=" -e \"$ARG\""
  fi
  eval ${CMD}
}

while getopts ":n:h" OPT; do
  case $OPT in
  n) HOST=${OPTARG};;
  h) usage
    exit 0
    ;;
  :) echo "-$OPTARGはホスト名が必須です"
    exit_abnormal;;
  esac
done
call_ansible_script
exit 0
```

以上
【数理最適化問題】包絡分析法(DEA)モデル

[前回](https://qiita.com/yoshi-k312/items/fee164d95a9f7d8826cc)の続き

包絡分析モデルをやろうとしたが、Pythonでのやり方があまりわからず検索して出てきたRでの方法でやってみた。

例のごとくサンプルの問題はこちらのサイトから引用している
[NTTデータ数理システムNumerical Optimizer Sample問題集](https://www.msi.co.jp/nuopt/docs/v19/examples/html/02-00-00.html)


# 包絡分析法(DEA)モデル
例題は次のページを参照
[2.4 包絡分析法(DEA)モデル](https://www.msi.co.jp/nuopt/docs/v19/examples/html/02-04-00.html)
条件の異なる店舗からそれぞれの効率を分析する。
従業員や営業時間をコスト、売上をパファーマンスとしコストパファーマンスを分析する。
Rのベンチマークライブラリを用いて分析する。
こちらを参考
[【R】包絡分析（DEA)や確率フロンティア分析（SFA)のRパッケージ: Benchmarking](https://keita43a.hatenablog.com/entry/2019/07/10/230209)


```R:DEAモデル
# ライブラリインストール(任意)
install.packages("Benchmarking")

# ライブラリインストール
library(Benchmarking)

# コストをインプット
x <- cbind(c(5, 10, 20, 20, 30, 50),c(24, 12, 12, 24, 12, 12))

# アウトプットとなるパフォーマンス
y <- matrix(c(2, 6, 10, 12, 12, 20),ncol=1)

# deaを使って分析する
e <- dea(x,y, RTS = "drs", ORIENTATION="in")
eff(e)

```


```R:出力
# 結果
0.666666666666667・1・1・1・0.9・1

```

6個の数値が出力された。6店舗あったのでこれがそれぞれの効率(コストパファーマンス)になる。
一番効率が良いものを1として、それぞれの効率を表している。
つまり1番目の店舗は効率が良い店舗に比べて効率が悪く約67%の効率であることがわかる。
Macで各種ビデオ会議ツールを使うときに画面共有ができないときに確認すること

私の会社では、主に ZOOM や Discord を使ってオンライン会議だったり、オンライン飲み会だったり、オンライン勉強会なんかをやっているのですが、
先日私の画面を共有しながら発表を行おうとしたらうまくいかずにしばらくハマってしまったので忘れないようにメモ。

> 今思えば、以前 Chatwork 使っていたときも似たようなことでハマった気がする。
私ってば、学習しない人ですね。


## さいしょにまとめ

- 「システム環境設定」から「セキュリティとプライバシー」を開く
- 「プライバシー」タブを開く
- 「画面収録」メニューから画面共有を使いたいアプリにチェックを入れて画面収録を許可する

## おきていたこと

- 仕込んでおいた勉強会用スライドをフルスクリーン表示にして、ZOOMやDiscordでその画面を共有しようとしたら、相手にはデスクトップの壁紙しか見えていないという状況になった
- なぜか、ZOOM本体やDiscord本体は見えているし、壁紙だけの画面は配信されているので配信設定の問題ではなさそう

## 原因

ビデオ通話ツールは自分のデスクトップや特定のアプリの画面をリアルタイムにキャプチャーして参加者と共有できる機能を持つものが多いですが、これらのようにユーザーが意図的に自分のデスクトップ画面を配信するつもりでつかうものだけでなく、世の中には悪意のあるツールなんかも存在しています。

それらが勝手に画面を共有できないように、OS側はアプリのそういった操作をユーザーが明示的に許可しない限り配信できないような仕組みになっているのですね。

> はじめて画面共有をしようとしたときにダイアログがでたりすることもあるようですが、事前に仕込んでおかないといざ自分の番になったときに出ても結構わたわたしてて見落としてたりうっかり閉じてしまうこともあるかもしれません。そうなると今回のように何故か画面はキャプチャできてもアプリが見えない状態になってしまうようです。

## 解決方法

> 注意１：以降キャプチャが英語版ですが、~~これは私が特に意味もなくかっこつけて言語設定を英語にしているだけですので~~そんな細かいことは気にしないように。
説明自体は「日本語表示」時の項目名で書いていきますし、最悪枠線つけてる箇所のアイコンだったり、位置関係を見て判断してください:bow_tone1:

> 注意２：世の中では最新 OS の Big Sur が登場してますが、私はまだアップデートをビビってるためキャプチャ内容は Catalina のものです。
Big Surでもし劇的に画面構成やアイコンが変化していたら…ごめんなさい。

### １．システム環境設定を開きます。

お好きな方法でどうぞ。

- メニューバーの一番左にある「（リンゴマーク）」をクリック→「システム環境設定」を選択します
- 買ったばかりの Mac なら Dock にもいるかもしれません
- Spotlight から探してもよいでしょう
- Siri にお願いしてもOK
- もちろん、お気に入りのランチャーから立ち上げても大丈夫

### ２．「セキュリティとプライバシー」をクリックして「セキュリティとプライバシーパネル」を開きます。

![system_preferences.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25724/fc3f19f4-f3fd-16c3-dd76-abab262b7068.png)

ぱっと見つけられない場合は、システム環境設定の右上にある検索窓に「セキュリティ」とかいれるとすぐ見つかるはずです。

### ３．「プライバシー」タブを開き、左のリストから「画面収録」をクリックします

![security_and_privacy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25724/f159dd50-7f0d-1ba9-690a-01ad64122fd0.png)

### ３．右のリストからビデオ通話アプリを選択

画面収録をクリックすると、画面収録を行う可能性があるアプリ（だと思います）が一覧で出てきますので、使いたいビデオ通話アプリ（キャプチャの例だと ZOOM）の横にあるチェックボックスをオンにします。

これでチェックを入れたアプリで画面共有ができるようになるはずです。

## 参考

- [Macの画面収録へのアクセスを制御する](https://support.apple.com/ja-jp/guide/mac-help/mchld6aa7d23/mac)
pgAdminがロード中から動かない

#PostgreSQLのpgAdminがずっとロード中・・
PostgreSQLを使う機会があったのでインストールしたんですけど
pgAdminがロード中のままいつまでたっても動かないんですよ
なんだかjsの扱いがうまくいってない？ような感じです
前に入れたときはそんなことなかったのに。
日本語で同様の記事を見つけられなかったので書いときます

##環境
OS：Windows10 64bit
DB：PostgreSQL9.6＋pgAdmin4.28（その時点で最新）
ブラウザ：FireFox83（chromeとかも試してみたけど同じでした）
DBは普通に動作してますが、pgAdminがちゃんと開かない

##解決法
レジストリいじるので自己責任でー
①レジストリエディタを起動します
②[HKEY_CLASSES_ROOT\\.js\Content Type]を
　[text/plain] から [text/javascript]　に変更
③pgAdminを再起動
④開けた！！！

##結論
きっと何か変なとこをいじったんだろうなぁ
誰かのお役にたてれば幸いです

##参考というか回答
安定のスタックオーバーフローさん
https://stackoverflow.com/questions/64840826/pgadmin-4-v4-28-keeps-loading

##追記
2020/12/28 
参考のとこのサイト更新されてました
環境によって発生するpgAdmin4.28のバグだったっぽいですね、次バージョンからは解消されるみたい
Org-babel で リモート環境でshell scriptを実行する方法

```
#+BEGIN_SRC sh :prologue "tmux attach" :dir /ssh:[servername]:~/.ssh
ls
#+END_SRC
```
コードブロック上でC-c C-c (org-ctrl-c-ctrl-c) すると、結果が帰ってくる。


```
#+RESULTS:
: authorized_keys  id_ecdsa  id_ecdsa.pub  id_rsa  id_rsa.pub  known_hosts
```
# 参考リンク
https://emacs-orgmode.gnu.narkive.com/S41o7Sb0/o-executing-org-shell-blocks-on-remote-machine-over-ssh
「俺の仮想マシンルーターがこんなに速いはずはないわ」と思って作った件

# 概要
この記事は @tnishinaga さんの「[俺の仮想マシンルーターがこんなに遅いはずはない/ KernelVM online 1](https://speakerdeck.com/tnishinaga/kernelvm-online-1)」のタイトルを~~若干パクって~~オマージュしたものになります。
「とりあえずそれなりに妥協して動けばいいや」という具合なのでセキュリティとかいろいろ考慮してないのでご了承ください。
~~あ、2020年の自分の誕生日ネタです。言わなくてもわかると思いますがｗ~~

# ~~(始めに言っておく)~~まとめ
> ~~いくら VirtIO を有効にしていてもオーバーヘッドとか VM に載せる OS が違ったりすると速度が上がるわけじゃないかもしれないよ~~
> VirtIO を有効にしたらゲスト OS の設定をちょっと確認してごらん。世界がちょっと変わるかもしれないよ？

# きっかけ
「[以前書いた願望](https://qiita.com/soprano1125/items/11c20b0ffebc38d467cb)」より
> そろそろ仮想化に意欲的になったり「[IPv6 IPoE](https://qiita.com/soprano1125/items/65295cd8c371abc6ebe8)」に興味を持ったりしますが、ハードの予算は取れないしガラケーの需要も減りつつあるし周りも「は? 新しいハード? インフラ? インターネットなんてできりゃいいじゃん、そんなのに金使うくらいなら(ry」という感じでかなり消極的だったりですがいつかは新鯖投入して「今使っている PC ルーターの仮想化」に挑戦したいですね(いつとは

# 買いました
ヤフオクと某なんちゃら給付金を用いて買いました。

* NEC Express5800/S70 タイプRB(@ヤフオク)
    * CPU: Xeon X3430
    * メモリ: 9[GB]
    * GPU: Quadro FX570
    * HDD: 320[GB]
* Gigabit LAN カード,Broadcom BCM5751純正ボード[^bcm5751]  x2(@amazon.co.jp)

トータルで3万円ぐらいですが、12年前に組んだ Cerelon PC ルーターより安くてグレードが高ｋ（ｒｙ

# セットアップ
* みんな大好き CentOS 7 x86_64 を Express5800 に
    * VM のホストにグローバルな IPv6 のアドレスを付けてなにかやることがないのでローカルホスト以外つけていません。
* VM のゲストにルーターをポンと構築
    * 「まぁ多少のオーバーヘッドはしょうがないかー」精神で
    * 「フレッツ光ネクスト ギガラインタイプ」相当の線にしたのでどうせなら「フレッツ光ネクスト ハイスピードタイプ」の上限 200[Mbps]以上が出ればほぼ十分
* とりあえず PPPoE のやりとり用に FreeBSD、IPoE のやりとり用に Debian
    * 両方 FreeBSD が良かったのですが早く IPoE の線でいろいろ遊びたくてファイアウォールのルールがネットで転がっている Linux に
    * 最後のまとめの方にも書いていますが最終的に FreeBSD だけ VirtIO を無効にして e1000e にしています
* ブリッジは OpenvSwitch 
    *  macvtap でも良かったのですが「OpenvSwitch にフレッツ直結してみた」という一例が見当たらなかった~~し面白そうだった~~ので OpenvSwitch にしたのもひとつあります

# ネットワーク構成 / 計測条件
![network.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19210/cedffe40-02e9-1b7b-41d7-98759d87a510.png)

計測サイトは以下を使用しました。

* iperf.scottlinux.com @ iperf3
* [SPEED TEST Powered by RBB SPEED TEST](http://www.speed-visualizer.jp/) @ ブラウザ
iperf3 は10秒間のスループットを計測しました。

# 計測結果
![iperf3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19210/5b470168-64aa-c75c-6b29-b33951815847.png)
![SPEEDTEST by RBB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19210/c7b4cc3e-7e5a-7177-ca3d-3fb322854b0f.png)
FreeBSD の VM で VirtIO を有効にして PPPoE で外とのやりとりをしたらダウンの速度は出るけどアップの速度が出ないという結果に。それ以外はまぁまぁなところなのかなと
ただ、たまたま FreeBSD で ookla のスピードテストを走らせるとアップの速度が出るようなのでファイアウォール(の PF)あたりがなにか悪さしてるのではないかと~~いらぬ~~推測をしてみたり・・・
~~何はともあれとりあえず VirtIO ではなく e1000e にしてお茶を濁すことにして、v4 over v6 のルーターを作ればいいかということにしました。v4 PPPoE でもまぁまぁ使えてますしｗ~~ → [解決編](https://qiita.com/soprano1125/items/9c2b27ea4254e6eb6d2f)をアップしました。@ 2021/02/22

# まとめ
~~いくら VirtIO を有効にしていてもオーバーヘッドとか VM に載せる OS が違ったりすると速度が上がるわけじゃないかもしれないよ~~
VirtIO を有効にしたらゲスト OS の設定をちょっと確認してごらん。世界がちょっと変わるかもしれないよ？

# おまけ
VPS とかパブリッククラウドなサービスを使ってるわけではないの Public な iperf のサーバーを探して使いましたが日本国内には正直見つからなったのでどなたかやらないですかね？(SoftEther さんや JANOG で見かけた i-measure な皆さんを遠目で見ながら

[^bcm5751]: 追加で HDD を投入した関係で Intel NIC だと若干お高くなったので妥協しました。~~「蟹は嫌だ…蟹は嫌だ嫌だ…！」「BroadCom！！」~~
【VSCode】WindowsでのGo開発環境構築

社内で、[A Tour of Go](https://tour.golang.org/welcome/1)を使ってGoの勉強会をしているので、学んだことをメモしておく。
まとめ記事は[こちら](https://qiita.com/eyuta/private/77ac58e4d9141898c733)。

初回はWindowsでGoの開発環境を整える。
本当は[A Tour of Go](https://tour.golang.org/welcome/1)上で開発をしたかったが、Web上では補完効かなかったため、急遽vscodeでの開発に切り替えた。

### 前提
- vscodeインストール済み

### 手順
1. [こちら](https://golang.org/doc/install)から、Goをインストールする
2. vscodeを起動
    - Goをインストールする前にvscodeを起動していた場合、vscodeのterminalに環境変数が反映されないので、vscodeを再起動する必要がある
    ![not_fount_go.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110860/4791c313-51fa-d1b1-bfa1-e133a88cae9a.png)
3. vscodeに[Goの拡張](https://marketplace.visualstudio.com/items?itemName=golang.Go)をインストール
4. Goファイルに各種エディタのサポートを効かせる場合、以下の画像のように `Go: Install/Update Tools`コマンドを用いて、必要なツールをインストールする( `Ctrl+Shift+P` でコマンドパレットを開く)
  ![go_install_tool_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110860/60a5d330-9b0e-94c8-8333-bb3490950dc2.png)
  ![go_install_tool_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110860/617b7e06-2b32-e921-c324-7991367b1712.png)

5. デバッグも、上で`dlv(delve)`をインストールしていた場合、[他言語と同様の方法](https://code.visualstudio.com/docs/editor/debugging)で可能
  1. `Ctrl+Shift+D` で Run Viewを開く
  2. launch.jsonを作成 (typeはgoで)
  3. `Debug: Start Debugging`コマンドでデバッグ開始

### 所感
今日はここまで。

他言語の環境構築記事では、環境変数(GOPATH)の指定や各種ツールのインストールも自分で行っていた。
しかしGoの場合は、Goをインストールしたりら後は全部VSCodeで完結できるので、自分でやることは驚くほど少ない。感動。


今日は環境構築で終わったので、明日から本格的に`A Tour of Go`を進めていく。
【JavaScript】コールバック関数の型【メモ】

## 第一引数と第二引数の値を処理する関数

```JavaScript
function doSomething(a, b, callback) {
  const result = callback(a, b)
  console.log(result)
}
// 掛け算をする関数
function multiply(a, b) {
  return a * b
}
// 足し算をする関数
function plus(a, b) {
  return a + b
}
// ...

// doSomething関数を実行すると、第一引数の2と第二引数の2を掛け算し、4が出力される
doSomething(2, 2, multiply)

// 第3引数にplusを入れた場合は、2+3が実行され、5が出力される
doSomething(2, 3, plus)
```
## 思ったこと
最初に、今回でいう「doSomething()」のような関数を用意しておくことで、後々に別の機能（例えば引き算させる関数「minus」など）を追加する際に、記述量が少なく済み、可読性も上がると感じました。
Goキャッチアップまとめ

## はじめに
Go言語をキャッチアップするため、[A Tour of Go](https://tour.golang.org/welcome/1)を進めてみた。
その時の内容を残しておく。

## A Tour of Go

1. [WindowsでのGo開発環境構築](https://qiita.com/eyuta/private/afcb4f7bc194f0209f47)
2. [A Tour of Go メモ ~Packages, variables, and functions~](https://qiita.com/eyuta/items/88b4ffef9ab4f08c0908)
3. [A Tour of Go メモ ~Flow control statements: for, if, else, switch and defer~
](https://qiita.com/eyuta/items/c85146cbca1da24189d7)
4. [A Tour of Go メモ ~More types: structs, slices, and maps~](https://qiita.com/eyuta/items/cbbe41247880c1e21857)
5. [A Tour of Go メモ ~Methods and interfaces~](https://qiita.com/eyuta/items/f2d87b5bde6b979a733f)
6. [A Tour of Go メモ ~Concurrency~](https://qiita.com/eyuta/items/0bddf8fc9cf05bb175dd)
【git】pushしてしまった後に過去コミットに戻す方法

### `gitでリモートにpushしてしまったけど、過去コミットに戻したい！`そんな時の攻略法を簡潔に紹介

##1 git log でコミットの　番号を確認する

````
$ git log
```

するとこんな感じで出てくる

```
commit 6ca09f7747e6ef84761d9d33a8373731836877eb (HEAD -> feature/tweet_list, origin/feature/tweet_list)
Author: nozomi <kkk@docomo.ne.jp>
Date:   Sun Nov 22 13:23:21 2020 +0900

    ページネーションを実装

commit cc2ede3638ebe6a6b768aa1fd269a2262e79d400
Author: nozomi <kkk@docomo.ne.jp>
Date:   Sun Nov 22 12:44:28 2020 +0900

    seed画像をビューに表示。アップロード画像をgit管理下から排除


```


今回は
`    seed画像をビューに表示。アップロード画像をgit管理下から排除`に戻りたい想定で説明を続けます！

戻りたいコミットの番号をメモしとく
今回の場合は、`cc2ede3638ebe6a6b768aa1fd269a2262e79d400` が番号になります。

##2 `git reset --hard 番号`を使い、指定コミットに戻す。

 今回は
`seed画像をビューに表示。アップロード画像をgit管理下から排除`に戻す処理なので、以下のように書きます。


```
$ git reset --hard cc2ede3638ebe6a6b768aa1fd269a2262e79d400
``` 

##3 リモートリポジトリに強制push
```
git push -f origin HEAD
```
 

これにて完了です。
初心者から学ぶDB設計

#テーブル設計の3つのstep

####1.概念設計
####2.論理設計
####3.物理設計

#1.概念設計

エンティティを見つける。
エンティティとは物や出来事に対応する概念。

帳票からエンティティを抜き出す。

例:注文、顧客、商品

帳票に存在する項目がどのエンティティの属性になるか考える。
顧客エンティティ
→顧客番号、顧客名、住所

商品エンティティ
→商品番号、商品名、単価

ER図を書く。

繋がるエンティティに線を引く。

#2.論理設計
テーブルに主キー列を設ける。
・主キーはテーブルの列で1番上に記載。
・主キーには下線をつける。

結合するカラムの外部キーを設定する。
1対多の関連について1の方の主キーを他の方のFKにする。

関連の多重度を明らかにする。
1対１か1対多か。

####多対多の場合
交差テーブルを作成する。
多対多が存在しないようにする。

####1対1の場合
データベースの観点からはテーブル数は少ない方が良い。
1対１の場合どちらかが補助的な役割になっているので統合する。

####重複して存在する列を削除する
履歴テーブルなどは問題あることも。

####他の列から計算できる列を取り除く

####最終確認 正規形になっているか
1.主キーの一部の値が決まると値が決定する列がないこと。
2.段階的に値が決定しまう列がないこと。

####列に設定するデータ項目の特徴を整理

#3.物理設計
Oracleのストレージ領域割り当てについて。

あらかじめ表領域を割り当てる。

CREATE TABLESPACE <表領域名>　DATAFILE '<データファイルのパス>' SIZE <サイズ>[REUSE][AUTOEXTENDON],....

|パラメーター|内容|
|---|---|
|データファイルのパス|データファイルのパス。一般的にはdbf|
|SIZE<サイズ>|データファイルのサイズを指定。|
|REUSE|指定したデータファイルのパスに、既にデータファイルが存在していた場合は再利用する。|
|AUTOEXTEND ON|自動拡張ON|

例)
sql>CREATE TABLESPACE tbs01 
2 DATAFILE 'c:/oracle/oradata/tbs01_1.dbf' SIZE 100M AUTOEXTENDED ON 
3 ,'c:/oracle¥oradata¥tbs01_2.dbf' SIZE 100M AUTOEXTEND ON;

####テーブル作成時に格納先表領域を指定
CREATE TABLE tbl01(id NUMBER,col1 VARCHAR2(100)) TABLESPACE tbs01;
それぞれのユーザーにデフォルトで表領域が決まっているが、ユーザーのデフォルト外の表領域を選択する場合は表領域の指定が必要。

表領域削除の場合は、中にあるデータファイルも同時に消さないとエラーが発生する。
DROP TABLESPACE <表領域>　[INCLUDING CONTENTS [AND DATAFILES]];
INCLUDING CONTENTS:格納したオブジェクトとともに。
AND DATAFILES:DATAFILEとともに。

####制約を決める
値が決まっているもの→チェック制約
（選択肢）

NOT NULL制約

主キー制約
外部キー制約
一意性制約

####インデックスをつける列をきめる
Oracle:主キー、一意キーには自動でインデックスがついているので必要なし。

####テーブルインデックスのサイズを見積もる
Oracle:テーブルのコストを見積もるプロシージャとしてDBMS_SPACE.CREATE_TABLE_COST
インデックス:DBMS_SPACE.CREATE_INDEX_COST
が存在する。

####オプジェクト(テーブル、インデックス)を格納する表領域を作成
CREATE TABLESPACE order_tbs DATAFILE 'C¥oracle¥order_tbs01.dbf' SIZE 100M AUTOEXTEND ON;

#### オブジェクトの所有ユーザーを作成
CREATE USER order_app IDENTIFIED BY password QUOTA UNLIMITED ON order_tbs;
order_appユーザーを作成

GRANT CREATE SESSION TO order_app;
order_appユーザーにcerate session権限を付与

#### 決定事項を設計書にまとめる

#### CREATE文の作成
M1 MackbookでAmazon EBSをマウントする

我がM1 MackBookの、蓋開けから画面点灯まで速すぎるとか、Safariの動作が爆速過ぎるとか、電池が長持ちし過ぎて電源ケーブルつけてないことを忘れるとか、色々快適すぎて毎日macをいじる今日この頃。今回は、SSHFSを使ってAWS EC2ボリュームをマウントしたので、その時のメモです。ちょうどApple Silicon対応したDeveloper Previewがあったので、ありがたく使わせていただきました。

#FUSE for macOSをインストール

https://osxfuse.github.io

Apple Silicon対応のDeveloper Preview macFUSE 4.0.0以降をダウンロード＆インストール

※SSHFSだけに用があったのですが、FUSE for macOS(macFUSE？)も必要とのことで先にインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/7006201a-4005-1fa3-53dc-c25ef05af610.png)
真ん中のInstall macFUSEを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/0de5243c-22b0-f848-f294-3ceb1b19261e.png)
途中、以下のダイアログが出ますので指示通りに、環境設定を開きます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/7bb9f4b0-b551-7959-3ad3-32c467a8240a.jpeg" width="40%">

一旦電源切る -> 電源長押し -> パスワード解除 -> 起動セキュリティユーティリティ -> "Machintosh HD"のセキュリティポリシー -> 低セキュリティ -> 確認済みの開発元から...のチェックを有効 -> システム終了

起動 -> セキュリティとプライバシー -> 鍵アイコン解除 -> 開発元"Benjyamin... を許可 -> システム再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/192e92d8-08d5-9733-7980-a7b51449ead9.png)

#SSHFSをインストール

トップページからSSHFS 2.5.0をダウンロード＆インストール
![スクリーンショット 2020-11-24 11.14.30.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556119/d8b8bed0-a3f3-278d-b422-ec2ee79b0869.jpeg)
完了後、```sshfs```を実行すると以下のようなエラーが出るので、

```
dyld: Library not loaded: /usr/local/lib/libosxfuse_i64.2.dylib
```

リンクを貼る。

```
cd /usr/local/lib
sudo ln -s libfuse.2.dylib libosxfuse_i64.2.dylib
```

# Amazon EBSをマウントする

```
sshfs -o IdentityFile=private-key.pem　user-name@xxx.amazonaws.com:/home/user-name/share mount-point
```
なお、アンマウントは```fusermount```でなく```umount```で良い。

#アンインストール　(2021/09/17)

macOS Montereyのアップデートに向け、ファイルシステムに深く影響しそうなものを入れたままだと怖いので、削除してみました。

**ご注意**

- 多分消されているとは思いますが、ちゃんと確認まではしてませんのであしからず。
- 削除し終わってから投稿を思いついたので、画像がなくてすいません。

まずはmacFUSEから。

1. システム環境設定　->　macFUSE
1. Show Beta Versionsのチェックがないことを確認する（あったらチェック外す）
1. Remove FUSEをボタンを押す。
1. Terminal起動し、```cd ~/Library```。
1. ```ls -lafR | grep fuse```で関連しそうなファイルの残骸を片っ端から削除。私の環境では~/Library/Caches、Saved Application Stateフォルダに残骸がありました。

次にsshfsを削除。

https://qiita.com/ysk24ok/items/2202b483cd068ec824eb

上記を参考にします。

```
sudo rm /usr/local/bin/sshfs
sudo rm /usr/local/share/man/man1/sshfs.1
sudo pkgutil --forget com.github.osxfuse.pkg.SSHFS
```

最後にmacOSを再起動。

以上
Re:VIEW Starterをインストールするときに少し手間取った話(gem installでpermissionエラー)と解決方法

# はじめに
技術書でもしたためようとRe:VIEW Starterをインストールしました。
そこで、gem installで手間取ってしまった話とその解決方法を書きます。

# 困ったこと
しかし、[Re:VIEW StarterはRe:VIEW 2.5をサポートしており、3.0や4.0はサポートしていません](https://kauplan.org/reviewstarter/)。

まちがって、下記のコマンドで

```
gem install review
```

最新のreviewをインストールしてしましたが動きませんでした。なので、

```
gem uninstall review
```
で削除しました。そして、バージョン指定で入れ直してみました。

```
gem install review --version=2.5
```

が、下記のようにパーミッションエラーが起こりました。

```
$ gem install review --version=2.5
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
```

# 解決方法
このエラーコードで検索をかけると、[「gem installでpermissionエラーになった時の対応方法」](https://qiita.com/nishina555/items/63ebd4a508a09c481150)がヒットし、参考になりました。
なるほど...rbenvでrubyを管理した方が良いということがわかりました。
>システムのrubyを利用しているため、権限不足でgemのインストールができない可能性が高い...
ルート権限でシステムのRubyにインストールをしてもいいのですが、開発環境ではrbenvでrubyを管理することをおすすめ...

上記の記事の手順に従って、ターミナルからインストールを進めます

```
brew update
brew install rbenv ruby-build
```

下記のコマンドで最新のバージョンを確認して

```
rbenv install -l
```

rubyをインストールしました。

```
rbenv install 2.7.2
```
バージョン2.7.2を下記のコマンドでグローバルで利用するように変更しました。

```
rbenv global 2.7.2
```

下記のコマンドで確認すると、変更されていることが確認できました。

```
rbenv versions
  system
* 2.7.2 (set by /Users/takudooon/.rbenv/version)
```

# rbenvにパスを通す
>
rbenvにパスを通すため、シェルの設定ファイル(.bashrcや.zshrc)に以下を追加します。


上記の.bashrcがどこに探しても見つからず、悩みました。
検索していると[「bundle installしてもpermissionsエラーが起きるときの対処法」](https://qiita.com/edasan/items/288604b78e5cf6407d0e)という記事がヒットしこちら参考になりました。

viコマンドで設定ファイルをひらけて、

```
vi ~/.bash_profile
```

rbenvにパスを通すために下記の設定ファイルの/.bash_profileに書き込みました。

```
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

そして,下記のコマンドでシェルを再起動しました。

```
exec $SHELL -l
```

# おわりに
上記の方法で無事Re:VIEW Starterを動かすことができ、vscode上でpdf出力をすることができました。
簡単！ MAMPでgensim、word2vecを使う。

**注意！ python、mamp、gensimがインストールされた環境の方にむけたものです。できてない方はインストールしてください。**
**あと、word2vecの学習ではなく、似ている言葉探すだけです。**


まず、phpからpythonに接続します。

phpにこれを入れてください〜！
execというコードは、phpからコマンドラインにアクセスできます。（macのターミナルと同じやつ。）

```php

<?php
exec('ls')
?>
```

これを使って、word2vecが書かれたpythonを実行します。
例えば...、test.pyのようなpythonファイルをphpから実行できます。

```php

<?php
exec('python test.py')
?>
```

次にword2vecで似ている言葉を探すためにデータを持ってきます。
zipダウンロードしましょう。
http://www.cl.ecei.tohoku.ac.jp/~m-suzuki/jawiki_vector/
これを後で使います。


次にpython側ですが、新しいpythonファイルを作ってください。このように書きます。
これでok〜！
さっきダウンロードしたzipを回答して近くに置いてください。それが「entity_vector/entity_vector.model.bin」です。
**（今、日本語でコメントアウトで書いてある部分を消さないと読み込むときエラーが出るので消してください！（多分工夫したら読み取れる。なんかあると思う。））**

以下のようにsys.pathでパスを通してあげないと..
「ImportError: No module named 'gensim' 」というエラーが出ます。これはmampの中に設定されてるモジュールを探す場所が違うということです。なのですでにmacの中にインストールされたgensimのパスをターミナルで探しましょう。（pip show gensim）

```python:word2vec.py
# macのターミナルで、pythonでgensim modelsをインポートすることはできるんですが、mamp上にはパスが入ってません。
# なので、sys.pathでパスを入れてあげます。
import sys
sys.path.append('パス')
# 上の「パス」の部分には、次に調べる絶対パスを入力してください。（例：/Users/太郎/anaconda3/lib/python3.6/site-packages)

# 以下word2vecを実行するコード。
# 「graphic」と似ている言葉を探します。
from gensim.models import KeyedVectors
model_dir = 'entity_vector/entity_vector.model.bin'
model = KeyedVectors.load_word2vec_format(model_dir, binary=True)

results = model.similar_by_vector("graphic", topn=10, restrict_vocab=None)

for result in results:
    print(result)
```

では、phpに戻ります。
先ほどのexec()で、コマンドを実行し、pythonファイルを実行します。
第2引数には、結果が。第3引数には、エラーがあれば何かそれが返ってきます。
これで..結果は..

```php:index.php
$command = 'python wd2vc.py';
exec($command, $output, $return_var);
var_dump($output, $return_var);
```
いけた〜〜！！
「graphic」と似ている言葉が配列で出力されてます。やったね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276138/88c8d025-0090-4660-8270-f89b222edc9b.png)


参考記事：
PHP - exec()のエラーハンドリングと標準エラー出力の関係をまとめる
https://qiita.com/smd8122/items/65b552f1d53bfb7fad9a
MAMPのPHPからMecabを使おうとしたら少しハマった話！
https://dbym4820.hatenablog.com/entry/2017/10/18/171259
【Rails】コントローラーの処理をモデル内のクラスメソッドとして記載する。

#テーマ
コントローラー内に処理を記載していき、コードが冗長になったり、同じ処理を様々なアクションで使用する場合、一つのメソッドとしてモデル内で定義することがあると思います。
簡単なやり方と、その際にちょこっとだけつまづいた点をまとめています。

#バージョン
ruby 2.5.7
Rails 5.2.4.4

#やり方

```ruby:shops_controller.rb
def members
 
 @table_customers = 2
 @tables = 3

 @all_customers =  @table_customers * @tables
 Shop.update(members:@all_customers)
#店内の総客数を計算するアクション
end
```

上記のコードでは店内の客数を計算するアクションになります。
（簡略化のために今回は１つのテーブルの客数を２人、テーブル数を３卓と定義しています。）

このアクションをモデル内に定義する場合を順を追って解説します。

```ruby:shops_controller.rb
def members
 
 @table_customers = 2
 @tables = 3

 Shop.count_members(@table_customers,@tables)

end
```
コントローラーの記述

```ruby:shop.rb
def self.count_members(table_customers,tables) 

  @all_customers =  @table_customers * @tables
  Shop.update(members:@all_customers)

end
```

モデルの記述

`このままではエラーが発生しますが、解消方法はのちに記載します`

・コントローラー側の記載
`Shop.count_members(@table_customers,@tables)`
Shop = メソッドを定義したモデル名
count_members = メソッド名（モデル内に記載してあるもの）
(@table_customers,@tables) = 処理する際に渡す変数

それぞれの記述を簡単に説明するとこのようになります。

・モデル側の記述
def = メソッドを定義
self = クラスメソッドを使用する際に記述（インスタンスメソッドの場合は不要）
count_members = メソッド名
(table_customers,tables) = コントローラーで受け取った値を変数としてそれぞれ再定義（今回の場合は、table_customers = 2, tables = 3 になる）

インスタンスメソッドとクラスメソッドの違いについては別記事を参照して見てください。今回はクラスメソッドを使用しています。

##注意ポイント①
前述した通り、単純に処理内容をコピペした上記のコードでは想定した処理が行われずエラーが発生します。
その理由は``モデル内で変数を再定義していることため``です。

上記のコードでは、コントローラーで定義した@table_customers,@tablesの値をモデルに渡し、table_customers,tablesとして再定義していますが、モデルメソッド内で@table_customers,@tablesが使われており、そのような変数は定義されていないと言うことでエラーが発生します。

``コントローラーで定義した変数は、モデルの処理では使えない``と言う感じで覚えれば問題ないかと思います。

そのため、エラーを解消するには、、、

```ruby:shop.rb
def self.count_members(table_customers,tables) 

  all_customers =  table_customers * tables #２つの変数の@を削除
  Shop.update(members:all_customers)

end
```

モデル内の@table_customers,@talesの@を削除することで正常に動作します。
（all_customersはメソッド内で新たに定義される変数なので@を削除しなくても動作自体は問題ありませんが、消去した方がベターです）

##注意ポイント②
また、モデル内で定義した変数をメソッド外の処理や、view内で使用したい場合は注意が必要です。
コントローラーで定義した変数がモデル内で使用できないのと同様に、モデル内で定義した変数もモデル外では使用することができません。

クラスメソッド内で定義した変数をview等で使用したい場合は`戻り値`としてコントローラーに返す必要があります

仮にall_customersを戻り値として返したい場合

```ruby:shop.rb
def self.count_members(table_customers,tables) 

  all_customers =  table_customers * tables #２つの変数の@を削除
  Shop.update(members:all_customers)

  return all_customers #returnメソッドで戻り値を指定

end
```

```ruby:shops_controller.rb
def members
 
 @table_customers = 2
 @tables = 3

 @all_customers = Shop.count_members(@table_customers,@tables)
 #戻り値を格納するための変数を定義

end
```

モデル内で戻り値の指定、コントローラー内で変数の定義を行うことで、モデル内で扱った値をモデル外でも使用できます。また、カンマで区切ることで、複数の戻り値を取得することも可能です。
HTMLでよく使いそうなタグをまとめた

## はじめに
Qiita記事2回目です！
HTMLの使用頻度が高そうな要素をまとめました。
私はよくこれどういう使い方だったかなーみたいな感じで迷うので、そんなときに参照したいと思います。

(もし間違いがあったらご指摘して頂けると嬉しいです！)

## メインルート
html : HTML文書においてルート (基点) となる要素 (トップレベル要素) であり、ルート要素とも呼ばれます。他のすべての要素はこの要素の子孫として配置しなければなりません。

## 文書メタデータ
head : 文書に関する全般的な情報 (メタデータ)を含む要素、たとえばタイトル、スクリプト、スタイルシートなどへのリンクも含みます。
meta : 任意のメタデータ（文字エンコーディングやviewportなど）を提示します。
title : 文書の題名を定義し、ブラウザーのタイトルバーやページのタブに表示します。
link : 現在の文書と外部のリソースとの関係を指定します。この要素はスタイルシートへのリンクや、サイトのアイコンによく使用されます。

## セクショニングルート
body :  HTML文書のコンテンツを示す要素です。body要素は文書中に一つだけ配置できます。

## コンテンツセクショニング
header : 文章や該当のセクションの導入部分・ナビゲーションのグループであることを示す。見出し、ロゴ、検索フォーム、作者名などを含めることができる。
main : 文書内の主要な内容を表します。
footer : 
文書や該当のセクションの著作者に関する情報、関連文書へのリンク、著作権情報等を表す。
nav : 現在の文書内の他の部分や他の文書へのナビゲーションリンクを提供するためのセクションを表す。
section : HTML文書の中で単独のセクション (区間) を表します。セクションを表現するより意味的に具体的な要素がない場合に使用します。
h1,h2,h3,h4,h5,h6 : 見出し。1〜6段階で表すことができる。

## テキストコンテンツ
div : 汎用的に使えるひとかまりとしての定義です。
p : テキストの段落を表します。
li : リストの項目を表すために用いられます。
ul : 項目の順序なしリストを表します。

## インライン文字列意味付け
a : href属性を用いて、別のウェブページ、ファイル、メールアドレス、同一ページ内の場所、または他の URL へのハイパーリンクを作成します。

## 画像とマルチメディア
img : 文書に画像を埋め込みます。

## 最後に
誰かに教えることを前提として学ぶと定着しやすいということを聞いたのでアウトプットしてみました。
これは自分用のメモみたいなものですが、学んだことを自分なりに言葉にすることで学びになればいいかなと思います。
Swift 構造体まとめ

## 構造体
Swiftの構造体に関してまとめたので、記事として残しておきます。

### 構造体とは？
- 値型
- ストアドプロパティ の組み合わせによって、一つの値を表す
- 標準ライブラリで提供されている多くは構造体である
  - Bool String Int Array Dictionary
  - オプショナルは列挙型　タプルは型の組み合わせ　Anyはプロトコル
 
#### 定義
```swift
struct 構造体名 {
  構造体の定義
}


struct Article {
    let id: Int
    let title: String
    let body: String

    init(id: Int, title: String, body: String) {
        self.id = id
        self.title = title
        self.body = body
    }

    func printBody() {
        print(body)
    }
}

let article = Article(id: 1, title: "title", body: "body")
article.printBody() // body

```
#### ストアドプロパティ の変更による値の変更
- 構造体はストアドプロパティの組み合わせで一つの値を表す値型
- 構造体のストアドプロパティを変更することは、構造体を別の値に変更することであり、構造体が入っている変数や、定数への再代入を必要とします
- 値型の変更に関する仕様は構造体のストアドプロパティ の変更にも適用される

- 定数のストアドプロパティは変更できない
- 構造体のストアドプロパティの変更は再代入を必要とするため、定数に代入された構造体のストアドプロパティは変更できない

```swift
struct SomeStruct {
    var id: Int

    init(id: Int) {
        self.id = id
    }
}

var variable = SomeStruct(id: 1)
variable.id = 2
let constant = SomeStruct(id: 1)
constant.id = 2 // error
```
- メソッド内のストアドプロパティの変更にはmutatingが必要
- 構造体のストアドプロパティの変更は再代入が必要なので、ストアドプロパティを含むメソッドにはmutatingが必要

```swift
struct SomeStruct2 {
    var id: Int

    init(id: Int) {
        self.id = id
    }
//  mutating をつけないとerror
//　Cannot assign to property: 'self' is immutable
//　自動でつけてくれるようになる
    mutating func someMethod() {
        id = 4
    }
}

var some2 = SomeStruct2(id: 1)
some2.someMethod()
some2.id // 4 変更されている
```

#### メンバーワイズイニシャライザ
- デフォルトで用意されているイニシャライザ
- 型のインスタンスは初期化後に全てのプロパティ が初期化される必要がある
- 独自にイニシャライザを定義して初期化の処理を行うこともできます、
- 構造体では自動的に定義される　メンバーワイズイニシャライザというイニシャライザがある
- 型が持っている各ストアドプロパティと同名の引数をとるイニシャライザである

```swift
struct Article2 {
    var id: Int
    var title: String
    var boby: String

// 以下と同等のイニシャライザが自動的に定義される
//    init(id: Int, title: String, body: String) {
//        self.id = id
//        self.title = title
//        self.boby = body
//    }
}

let article2 = Article2(id: 1, title: "Hello", boby: "this is body")
article2.id      // 1
article2.title   // Hello
article2.boby    // this is body
```
- メンバーワイズイニシャライザのデフォルト引数
- ストアドプロパティ が初期化式とともに定義されている場合
- そのプロパティに対するメンバーワイズイニシャライザの引数はデフォで引数を持ち、呼び出し時の引数の指定の省略ができる

```swift
struct Mail {
    var subject: String = "(No Subject)"
    var body: String

// 以下と同等のイニシャライザが自動的に定義される
//    init(subject: String = "(No Subject)", body: String ) {
//        self.subject = subject
//        self.body = body
//    }
}

let noSubject = Mail(body: "Hello")
noSubject.subject // "(No Subject)"
noSubject.body    // Hello
let greeting = Mail(subject: "Greeting", body: "Hello!")
greeting.subject // Greeting
greeting.body    // Hello!
```

### まとめ
簡単にまとめたのでこちらに記載しました。
何かあればご指摘ください
【Rails】Mysql2::Error::ConnectionErrorの解消

Railsアプリにバリデーションを定義した後の、テストデータ登録の成功が目的の備忘録です。その為、バリデーションの定義、記述は終わっている状態です。
# データ保存したいのに、Mysql2に接続できない

Docker環境下のRailsアプリで、app/modelsにバリデーションを定義し、動作チェックの為にMySQLにデータ登録を試みました。そうしたら.....

```
Mysql2::Error::ConnectionError at /Unknown MySQL server host 'db' (0)
```

**MySQLに繋がってないよ**と怒られました。

[全く同じエラー](https://teratail.com/questions/289731)にハマっている方も居ましたが、解決策は載っていません。
記事に載っていた**docker-compose up**を実践するも、dockerは正常に起動していました。

いずれにせよ、データが登録できていないので、次はデータベースのチェックを行いました。

```
①rails db:create
②rails db:migrate
```
しかし、ダメでした。
下記はrails db:create実行後にターミナルに出力されたエラー

```
Unknown MySQL server host 'db' (0)
Couldn't create 'myapp_development' database. Please check your configuration.
rails aborted!
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (0)
/Users/athlaliel/test/qa-coin/bin/rails:9:in `<top (required)>'
/Users/athlaliel/test/qa-coin/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:create
(See full trace by running task with --trace)
```

この後も、色々試した結果、原因が分かりました。

Docker環境でアプリを作成しているのに、実際はローカル環境でひたすらコマンドを叩いていました。Docker上のコンテナでMySQLも管理されてる以上、見つかるわけがなかったです。

下記のコマンドを順に実行する事で無事にデータベースは作成され、更新も可能となりました。

```
①docker-compose exec web rails db:create 

②docker-compose exec web rails db:migrate
```

# バリデーションのデータ登録

データベースがDocker上に出来たので、テストデータを登録しバリデーションが機能しているか試します。**rails console**を起動し、テストデータを登録していきます。

バリデーションに記述する文言はここでは書きませんが、変数を定義して**<モデル名.create>**と入力します。
このコマンドでデータ登録が成功すれば、SQLと同じ文言が表示され、データの保存まで行います。その為、別途**<モデル名>.save**コマンドを入力する必要はありません。
![validate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638561/8b48cba1-2ccd-2095-f640-901ef99d5447.png)

![validate2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638561/b577968b-51ac-a5ce-750a-bc4cd1b3b1f1.png)
もしエラーが起きたら、下記コマンドでチェックして原因の追求を行います。

```
pry(main)> <モデル名>.errors

※user.rbというmodelsファイルがあれば、user.errorsとターミナルに入力します。
```
![validate3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638561/de35b14b-e39e-f9c1-2c68-d93f782d037d.png)

Mysql2::Error::ConnectionErrorのようなエラーに遭遇したら、自分が今どの環境で作業しているかのチェックを行ってみると良いでしょう。

参考記事
[Unknown MySQL server host 'db' (0)エラーが消えない](https://teratail.com/questions/289731)
[Active Record バリデーション](https://railsguides.jp/active_record_validations.html)