OmniAICreator/Qiita-1.07M huggingface dataset:
[JavaScript]eclipseでのJavaScript開発プロジェクト作成手順

JavaScript開発環境をeclipseに作りたいと思ったけど、やったことなかったので調べてみてせっかくなので備忘として残しておく。
ちなみにeclipseインストール済み前提の手順です。

■手順1. プロジェクト・エクスプローラ内で右クリックし、新規＞プロジェクト＞静的Webプロジェクト を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/e149755e-01db-faa8-1a53-d4d5ba9ff36a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/b2d147e4-7d57-c516-185f-6b601e94dbc4.png)

■手順2. プロジェクト名をつけて「完了」ボタン押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/6aaafc3a-8bfc-73a1-50da-3bb73b7245de.png)

■手順3. "JavaScriptリソース"と"WebContent"が入ってるプロジェクトが作成される！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/ae56caa9-e667-94d2-8084-fbdac39ebefa.png)

■手順4. ④"WebContent"フォルダにjsやhtmlファイルを作成していく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/3fe93b19-bade-faba-7c71-fdb0f4bc7b8c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/f65c5a17-2106-b746-2555-8bb1d6eb41a7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/784a7f0a-88d3-1730-1235-a0c9cbbab013.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/2b5544b7-11e3-c3dd-42ee-9b709ea610f9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/deb1b6f1-338c-f344-ba78-786cc24b31fb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190156/765135fe-8d76-337a-63f9-b7eb014dd302.png)

ということでスタートラインに立てたので、これから何か書いて動かしてみる予定です。
【Ruby on Rails】RSpec導入まで

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# RSpecとは？
Railsで用いられることが多いテストツールであり、テストコードを書いておくと自動でアプリケーションの動作をテストしてくれます。
またgemでinstallすることが可能です。


# RSpecの構成

- describe：テストの題名
- context：題名を詳細に分ける場合使用
- before：itの内容を実行する前に必要な記述があれば使用
- it：テスト内容

この中でも、describe　と　it　は必須になります。

# RSpecのインストール
Gemfileの group :test do の中を変更します。
デフォルトの記述は削除し、代わりに以下の４つのgemを記述します。

```rb:Gemfile
group :test do
  gem 'capybara', '>= 2.15'
  gem 'rspec-rails'
  gem "factory_bot_rails"
  gem 'faker'
end
```
```:ターミナル
$ bundle install
$ rails g rspec:install
```

実行後、app配下にspecフォルダが作られますので、
これを編集しながらテストを実行していきます。

また、config/environments/test.rb の下部にある下記を:silenceに変更します。

```rb:config/environments/test.rb
config.active_support.deprecation = :stderr
↓
config.active_support.deprecation = :silence
```
そして下記を実行します。

```:ターミナル
$ rails db:migrate RAILS_ENV=test
```


また以下を追加するとテストを通過した文言も表示されるようになるため、
設定をおすすめします。

```:.rspec
--require spec_helper
--format documentation <--追加
```
ここまでで導入はOKです。

次回から
controller、model、view
をテストする方法を紹介します。
[Rails] 投稿一覧をカテゴリー別で表示する方法

#前提
- Ruby 2.6.3
- Rails 5.2.4.4
- devise導入済（しなくてもいい）
- 基本的なページは完成している
- コントローラー名は今回gears
- gearモデルにはcategoryカラムが存在する
- 今回はログインユーザーにしか見えない投稿一覧なので、他ユーザーも閲覧できるようにしたい場合は`user_id: @user.id`を省いてください。

#やり方
###Controller
編集前

```Ruby:gears_controller.rb
 def index
   @user = current_user
   @gear = Gear.where(user_id: @user.id)
 end
```

編集後

```Ruby:gears_controller.rb
  def index
    @user = current_user
    @gear1 = Gear.where(user_id: @user.id, category: "住居系")
    @gear2 = Gear.where(user_id: @user.id, category: "料理系")
    @gear3 = Gear.where(user_id: @user.id, category: "火周り系")
    @gear4 = Gear.where(user_id: @user.id, category: "その他")
  end
```

###View
```erb:index.html.erb
<div class="category bg-success">住居系</div>
  <% @gear1.each do |gear| %>
    <div class="gear-index-item mb-20">
      <% if gear.image.attached? %>
        <%= image_tag gear.image, class: "index-img" %>
      <% else %>
        <img class="index-img" src="<%= "/images/default_gear.jpg" %>" alt="Index image cap">
      <% end %>
      <%= link_to(gear.name, "/gears/#{gear.id}") %>
    </div>
  <% end %>
  
  <div class="category bg-warning">料理系</div>
  <% @gear2.each do |gear| %>
    <div class="gear-index-item mb-20">
      <% if gear.image.attached? %>
        <%= image_tag gear.image, class: "index-img" %>
      <% else %>
        <img class="index-img" src="<%= "/images/default_gear.jpg" %>" alt="Index image cap">
      <% end %>
      <%= link_to(gear.name, "/gears/#{gear.id}") %>
    </div>
  <% end %>
   .
   .
   .
```

それぞれeach文で繰り返し処理を行う。

#結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777631/cf410c5b-b297-de30-efef-97753080d461.png)


#まとめ
####whereメソッドを使えば簡単に特定カラムでまとめられる！
git hubにpushしようとしたところ「fatal: The current branch develop/feature/discussion has no upstream branch.」と出てしまった場合の対応方法

#怒られた

```
$ git push
```
でコードをgit hubにアップしようとしたところ、
`fatal: The current branch develop/feature/discussion has no upstream branch.`

と怒られてしまいました。
これは、「githubが「知らんブランチなんやけど」と言っているようです。

#対応策

上流ブランチをあてがって上げればいいのですが、エラーの時にヒントを出してくれてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693241/91a32a2e-3ea8-b964-838e-8df2e2c13474.png)

なので、そのまま

```
$ git push --set-upstream origin develop/feature/discussion
```

とコードして、

```
$ git push
```

これで、パスワード入力したらOKです。

`Everything up-to-date`
マルチスケールシミュレーション特論

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# qiita\_links :<span class="timestamp-wrapper"><span class="timestamp">&lt;2020-10-14 Wed&gt;</span></span>

-   1.[README.org](https://qiita.com/szksjm/private/bccf33bc2cc9ba3d8618)
-   2.[emacs,qiita,gitについて](https://qiita.com/szksjm/private/42773136231999869a8a)
-   3.[チャート式 第2回まとめ](https://qiita.com/szksjm/items/b7ca41de9ed3b1942766)
-   4.[フィボナッチ数列](https://qiita.com/szksjm/items/ce2dcfc0d2202f8e1f39)
-   5.[google recruit](https://qiita.com/szksjm/items/7590bedf4504a8fff9b1)



------
 - **source** ~/grad_members_20f/members/szksjm/README.org
現場に行く前に身に着けるべき知識とは

#はじめに
今回は自分と同じようなエンジニア未経験者が実際に業務をする前に身に着けておいた方が良いという知識について共有したいと思います。よろしく御願い致します。

まず今回ご説明する内容は**山浦清透さん**のこちらの動画を参考にさせて頂きました。
**参考：[知らないと現場で苦労するプログラミングスキルTOP5](https://www.youtube.com/watch?v=KEF_J_f_NRo)**

詳しい説明は是非動画をご覧になって頂けたらと思いますので今回は要約して説明させて頂きたいと思います。それでは始めます。

#第５位　セキュリティ
まあセキュリティに関しては納得だと思います。情報が漏洩したり不正なアクセスなどがあったら会社の信用に大きな損失を与えてしまいますからね。会社にとってはセキュリティのことを良く理解していないうちはコードを書かせてもらえないところもあるくらい**超重要**です。

#第４位　ネットワーク
考えれば確かにって感じですが言われて気づかないと深く学ばないままになってしまいそうなところですね。それにIT関連の仕事に就きたいなら知っておくべき当然の内容ですね。
でもネットワークの範囲というのは広いのでなかなか大変そうです。とりあえず自分は**インフラ関係とTCP/IP**などは初めに学習したいと思います。

#第３位　Linux
基本的にサーバーのOSとして使われていることが多いのがLinuxだそうです。AWSの無料枠とかもLinuxですもんね。動画では特にディレクトリ構造やコマンドを覚えるのが大切という風に説明してくれています。

動画には出てこないのですが個人的にLinuxについておすすめなサイトがありましたのでご紹介したいと思います。
おすすめサイト：[Linux標準教科書](https://linuc.org/textbooks/linux/)

#第２位　SQL
動画では**「息を吸うようにSQLを書け」**と言われています。自分も情報収集をしているうちにSQLについての知識はとても大切でよく使うということを知りましたし全てのサービスにとってデータベースは必ず必要なものなのでここらへんはしっかり学習したいところですね。

#第１位　Git・GitHub
ソースコードの管理に非常に主流になっているシステム。これが出来ないとチーム開発が出来ないので**超重要**。動画でもとりあえず**これだけは必ずマスターして欲しい**と言われています。
自分もとりあえずはGitHubについての知識をまずは最優先につけたいと思いました。



#おわりに

いかがでしたでしょうか。
今回は実際にエンジニアとして働く前に知っておくべき知識について紹介させて頂きました。
自分もまだエンジニアとしては知識も経験もほぼゼロに等しいので今回参考にさせて頂いた**山浦さんの動画は非常に勉強になりました**。自分はざっくり要約して説明しましたので皆さんには**是非動画を見て頂きたい**と思います。動画には**しっかりとした解説**とそれぞれの学習に**おすすめな本やサービス**などを紹介されていますのでお楽しみに。
それでは今回はこのへんで失礼致します。

#この記事は以下の情報を参考にして執筆しました。
- [知らないと現場で苦労するプログラミングスキルTOP5](https://www.youtube.com/watch?v=KEF_J_f_NRo) 「きよとのプログラミング大学」
LaradockをベースにしたLaravelのボイラープレートを作りました！


# 自己紹介
皆さん、はじめまして！
記事の内容に入る前に、簡単な挨拶を。

人生初の記事投稿です。
これまでは気が向いた時に勉強して自己満足してたのですが
これからは、学習した内容とか日々の気付きなどを、せっかくなのでアウトプットしていけたらと思います！(メモとしても)
至らない点もあるかと思いますが、よろしくお願いします！

※2020/10/19 追記
記事を投稿して早々、GitHubにTemplateRepositoryというオプションがあることに気づいたので、そちらのやり方で使用方法の項目を修正しました。

# 概要
Laradockをベースにした、Laravelのボイラープレートを作ったので、
それの紹介と簡単なイントロダクションをします。

ボイラープレートだけ欲しい方は、下記のリンクからどうぞ！
https://github.com/ryuyaF/LaravelBoilerplateOfLaradock


# なぜ作ったのか
前から気になっていた[Laradock](http://laradock.io/)を触ってみた際に、結構使い勝手が良かったのと
勉強も兼ねて、自前のLaravelのボイラープレートを作ってみたいな〜と思っていたからです。

## 自前のボイラープレートっておいしいの？
Laradockのボイラープレート自体は、探せばいくらでも有用なものがあるので、ぶっちゃけ作る意味はそこまでないです。
ですが、今回自前で用意したメリットとしては、下記のようなものがあるかなと思います。

### Laradockのインストール方法をいつまでも覚えていられない
Laradockに限った話ではないですが、
私の場合はプロジェクトを作る際、大抵は作り方がうろ覚えです。なんとなくの流れを覚えている程度です。
その度に、公式ページを見て、細かい設定方法やルールを確認し、作ってもいいのですが、、、面倒ですよね。
作りたい時にパッと用意する。
そういう点に魅力を感じる方にはおすすめです。

### 好みの構成に出来る
自分好みって良いですよね。作業しやすいです。



# 簡単なイントロダクション
## ディレクトリ構成と解説
```
YourProjectName/
  └App/
  └data/
  └laradock/ ※サブモジュール
  └env-example ※laradockのenv-example
```

- App
    - Laravelのインストールディレクトリ
- data
    - mysqlのdataディレクトリ
        - ` DATA_PATH_HOST=../data `
        - 初期設定では、laradockディレクトリの直上(=プロジェクトディレクトリの直下)に設定されている
        - **※Volumeディレクトリを変えたい場合**は、`laradock/.env`の`DATA_PATH_HOST`を変更する
- laradock
    - [Laradockリポジトリのこの時点のコミット](https://github.com/Laradock/laradock/tree/89c9cfe09941bead05d63ec3c0fe9b9173ce0526)がサブモジュール化されている
    - 必要があれば、適宜Updateしていく
- env-exampleファイル
    - サブモジュールは特定コミットをCloneする
    - laradockのenvファイル共通化のため、カスタマイズされたものを配置している


## 使用方法

1. [リポジトリ](https://github.com/ryuyaF/LaravelBoilerplateOfLaradock)にアクセス
2. `Use This Template`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/1540b904-c83a-d790-c280-b42fe3057d3a.png)
3. 必要な情報を入力して`Create repository from template`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/9c3f4ffb-b884-6096-2d6e-34784f002b12.png)
4. ちょっと待つと、リポジトリが作成される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/1692c1a0-220f-fa8a-2149-68b033538a9f.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136820/5dbbd2fb-852e-abce-77bb-346ccca53d5b.png)
5. あとは、CloneするところからREADMEの流れに沿って作業すれば完了



## こだわりポイント
### Laradockリポジトリをサブモジュール化
Laradockを単にCloneしたものをリポジトリに含めるのではなく、サブモジュールとしてリポジトリに定義しました。
それによって、Laradockリポジトリの更新が反映しやすくなったかと思います。


### Laradockのenvファイルをカスタマイズして、自前のリポジトリにて管理
Laradockをサブモジュール化したことによって、Cloneする際に、Laradockの`env-example`ファイルが直接管理できなくなりました。
なので、`env-example`を外出しして、カスタマイズできるような構成にしました。

## XDebugの設定
今回はとりあえず、Laradockを使用したLaravelのボイラープレートの作成が目的でしたので、気が向いたら今後追記します。
Let's encryptの導入手順（Oracle Linux, RHEL,Centos7）

![スクリーンショット 2020-10-18 19.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242478/45734cf1-d125-5599-0f98-6f11cc19e3c3.png)
簡単にSSL化するならLet's encryptが定番のようですが、いざ自分がやってみようとすると思ったより手順が各所で違うことを書かれていたので、やってみた手順をメモしてみました。手元の環境はOracle Linux7.8です。


# 参考URL

let's encryptの公式サイトです。
https://letsencrypt.org/ja/getting-started/

certbotというツールを使用して設定するのがいいようです。
https://certbot.eff.org/lets-encrypt/centosrhel7-apache


Webサーバに使っているソフトウェアと、OSを選択すると、設定方法を教えてくれます。

# Certbotのインストール

snapというパッケージ管理ツールを使ってCertbotをインストールするようにと書かれているのですが、うまくいかなかったので普通にyumでインストールします。


```
# yum install certbot python-certbot-apache
```

# 設定

設定します。これだけで設定できるようです。

```
# sudo certbot --apache
```


実際にURLを実際に叩いて確認します。

![スクリーンショット 2020-10-18 19.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242478/d44b4f88-10f2-0dac-3ce7-15abcd12f9fe.png)




SSL化されています。

# 証明書の更新

このままだと期限が３ヶ月に設定されているため、手動で更新させる必要があります。

このコマンドで証明書が更新されるかテストします。 ` --dry-run ` をつけることでテストができるようです。

```
# sudo certbot renew --dry-run
```

実際に更新するときには

```
# sudo certbot renew
```
を使います。
自動で更新した方が便利ですので、cronで自動設定します。


少しでも参考になれば幸いです。
初心者がGitHubに自分のアプリを上げる方法

#前提条件
Githubに登録していること
アプリがあること


#大きな流れ
①ワーキングツリーを作成
②インデックスにファイルを登録
③ローカルリポジトリにファイルを登録
④リモートリポジトリと接続
⑤リモートリポジトリにファイルを登録

##前提
GitHubにアップしたいファイルがあるフォルダにがカレントディレクトリであること

##①ワーキングツリーを作成
```git init```
<br>.gitが生成されていることを確認
```ls -a```

##②インデックスにファイルを登録
```git add *```
<br>備考
*はワイルドカードで、カレントディレクトリにある全てのファイルをインデックスに登録している

##③ローカルリポジトリにファイルを登録
```git commit -m 'test'```
<br>備考
-mはコミットに対してコメントを付ける機能でつけてもつけなくてもいいです。
<br>確認
コミットされたことを確認
```git log```
Author: xxx
Date:   Sun xxx xx 17:35:23 2020 +0900 
 
 test


##④リモートリポジトリと接続
```git remote add origin https://github.com/xxxxxxxx/xxxxxxxx.git```

<br>備考
originはリモートリポジトリ名で、任意の名前をつけても良い。基本はorigin
https/://github.com/xxxxxxxx/xxxxxxxx.gitはリモートリポジトリURL。GitHubのウェブページでリポジトリを作成すると付与される。（多分リポジトリページにそれらしきものはある）

<br>確認
```git remote -v```
<br>備考
接続しているリモートリポジトリ先が表示される


##⑤リモートリポジトリにファイルを登録
```git push origin master```

<br>備考
masterはブランチ名。デフォルトがmaster。
自分の今いるブランチを確認したい場合は以下コマンド
git branch --contains

<br>確認
自分のGitHubのリポジトリページにアクセスしてアップロードされていることを確認
[Java]HashMap,TreeMap,LinkedHashMapのセットした値の保持順

##[Java]HashMap,TreeMap,LinkedHashMapのセットした値の保持順
Mapにはいくつか種類があるけど、格納した値がどの順番で保持されるか(どの順番で出力されるか)違いがある。よく見る(個人的に)Mapたちのそれをまとめた。
どのMapを使うかはこの特徴の違いで選ぶことが多い気がする。

|HashMap|TreeMap|LinkedHashMap|
|:---:|:---:|:---:|
|順序不定|keyの昇順|登録順|


以下、確認してみた。

```java:test.java
public static void main(String[] args) {
	final int key = 0;
	final int value = 1;
	HashMap<String,String> hashMap = new HashMap<String,String>();
	TreeMap<String,String> treeMap = new TreeMap<String,String>();
	LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<String,String>();

	String[][] keyValue = {{"Japan","America","China","Korea","India"},
							{"Tokyo","Washington D.C.","Beijing","Seoul","New Delhi"}};

	for(int i = 0; i < keyValue[key].length; i++) {
		hashMap.put(keyValue[key][i], keyValue[value][i]);
		treeMap.put(keyValue[key][i], keyValue[value][i]);
		linkedHashMap.put(keyValue[key][i], keyValue[value][i]);
	}
	System.out.println("HashMap の結果を出力！");
	for(String hashMapKey : hashMap.keySet()) {
		System.out.println( hashMapKey +" の首都は "+ hashMap.get(hashMapKey) + " です。");
		}
	System.out.println();

	System.out.println("TreeMap の結果を出力！");
	for(String treeMapKey :treeMap.keySet()) {
		System.out.println( treeMapKey +" の首都は "+ treeMap.get(treeMapKey) + " です。");
	}
	System.out.println();

	System.out.println("LinkedHashMap の結果を出力！");
	for(String linkedHashMapKey : linkedHashMap.keySet()) {
		System.out.println( linkedHashMapKey +" の首都は "+ linkedHashMap.get(linkedHashMapKey) + " です。");
	}
}
```

```txt:実行結果
HashMap の結果を出力！
Japan の首都は Tokyo です。
China の首都は Beijing です。
America の首都は Washington D.C. です。
Korea の首都は Seoul です。
India の首都は New Delhi です。

TreeMap の結果を出力！
America の首都は Washington D.C. です。
China の首都は Beijing です。
India の首都は New Delhi です。
Japan の首都は Tokyo です。
Korea の首都は Seoul です。

LinkedHashMap の結果を出力！
Japan の首都は Tokyo です。
America の首都は Washington D.C. です。
China の首都は Beijing です。
Korea の首都は Seoul です。
India の首都は New Delhi です。
```
よって、HashMapは順序不定、TreeMapはkeyの昇順(今回はアルファベットの昇順)、LinkedHashMapは登録順になっていることを確認した。
まぁでも毎回忘れちゃうんですよね。
package.json の config の使い方について

# config

package.json の config に項目を追加すると npm-scripts 実行時に環境変数として `$npm_package_config_xxx` ( `xxx` はプロパティ名) という形で使用できるようになります。

# サンプル

## npm-scripts で使用する

```json:package.json
{
  "name": "foo",
  "config": {
    "foo": "bar",
    "dev": {
      "port": 8080
    }
  },
  "scripts": {
    "start": "node ./index.js",
    "dev": "http-server -p $npm_package_config_dev_port"
  }
}
```

この場合、 `$ npm run dev` と実行すると `$npm_package_config_dev_port` が `8080` と解釈されます。

## JavaScript のプログラムから使用する

npm-scripts だけではなく、JavaScript のプログラムからも以下のように使用することができます。

```shell:index.js
console.log(process.env.npm_package_config_dev_port); # 8080 と出力される
console.log(process.env.npm_package_config_foo_bar); # baz と出力される
```

# 使い所

正直、使い所はあんまり思いつきません。

可能であれば npm-scripts はコマンドライン引数を `--` のオプションでコマンドに渡せるため、そっちのコマンドライン引数を使ったほうがいいと思います。

環境設定の外部ファイルで環境変数を読み込ませるよりは良さそうですが、 ローカルでの環境情報を package.json に書き込むことになってしまい、git で package.json が競合することになりそうです。

どうしても npm-scripts のコマンドライン引数で連携できないケース（連携しようとすると npm-scripts がやたら複雑になるケース）や npm-all-run などで複数箇所の設定を同時に行いたい時など、かなり使用するケースは限られると思います。
Bashのプロンプトのカスタマイズ

.bashrcに下記のように追記する

```bash:~/.bashrc
export PS1='[\u@\h \w]\$'
```

上記のように編集後再度bashにログイン（bash --login）するとプロンプトは以下のようになります。

```
[ユーザー名@ホスト名 ディレクトリ（フルパス）]$
```
|記号|意味|例|
|:--:|:--|:--|
| \h | ホスト名 | host　|
| \u | ユーザ名 | user |
| \w | ディレクトリ（フルパス） | ~/work/GitHub |
| \W | ディレクトリ | GitHub |
| \t | 時間 (24形式) | 23:29:38 |
| \T | 時間 (12形式) | 11:29:38 |
| \@ | AM / PM | PM |
| \d | 日付 | Wed Jun 20 |
| \D | 日時 | \D{%y/%m/%d %H:%M:%S}<br/>18/06/20 23:29:38 |
| \\# | コマンドの番号 (1, 2, 3...) | 1 |
| \n | 改行 | |
| \\\$ | 一般ユーザーの時 `$`、rootの時 `#` を表示| $ |

文字の色や書体を変えたい場合は以下のように記述します。

```bash:~/.bashrc
export PS1='[\[\e[1m\]\u\[\e[0m\]@\h \w]\$'
```

| 値 | 効果 |
|:--:|:--|
| 0m | 装飾なし |
| 1m | **太字** |
| 2m | 細字 (未対応) |
| 3m | *イタリック体* |
| 4m | 下線 |

| 値 | 文字色 | 値 | 背景色 |
|:--:|:--|:--:|:--:|
| 30m | <font color="#000000">黒</font> | 40m | <font color="#000000">■ </font>背景黒 |
| 31m | <font color="#AA0000">赤</font> | 41m | <font color="#AA0000">■ </font>背景赤 |
| 32m | <font color="#00AA00">緑</font> | 42m | <font color="#00AA00">■ </font>背景緑 |
| 33m | <font color="#AAAA00">黄</font> | 43m | <font color="#AAAA00">■ </font>背景黄 |
| 34m | <font color="#0000AA">青</font> | 44m | <font color="#0000AA">■ </font>背景青 |
| 35m | <font color="#AA00AA">紫</font> | 45m | <font color="#AA00AA">■ </font>背景紫 |
| 36m | <font color="#00AAAA">水</font> | 46m | <font color="#00AAAA">■ </font>背景水 |
| 37m | <font color="#AAAAAA">灰</font> | 47m | <font color="#AAAAAA">■ </font>背景灰 |
【2020冬】 TypeScript + Prettier + ESLint + VSCode の設定

## 概要

- `eslint-plugin-prettier` が非推奨になったらしい。
  - [いつのまにか eslint-plugin-prettier が推奨されないものになってた | K note](https://knote.dev/post/2020-08-29/duprecated-eslint-plugin-prettier/)
- 以下の要件を満たしつつ、ESLint の config から Prettier を分離したい。
  - VSCode からフォーマッタを実行できる。
  - 非 VSCode 民でも npm script からフォーマッタを実行できる。
  - CI でフォーマッタ未適用コードをエラーにできる。

## TL;DR

src: https://github.com/arx-8/try-separate-eslint-and-prettier/commit/0d0f92201ca2102f20893b26fd23a902621aba41

## やったこと

### VSCode からフォーマッタを実行

- 以下の通り移行。
  - prev: 拡張機能 `dbaeumer.vscode-eslint` + `.eslintrc.js`
  - next: 拡張機能 `esbenp.prettier-vscode` + `.prettierrc`
- 設定周りについて。
  - `esbenp.prettier-vscode` の設定値 `prettier.prettierPath` で、プロジェクトに install した prettier を使うようにする。
  - 設定値 `editor.defaultFormatter` にフォーマッタとして拡張機能 `esbenp.prettier-vscode` を指定したので、設定値 `editor.formatOn*` で prettier を実行できるようになった。

### 非 VSCode 民でも npm script からフォーマッタを実行

- `prettier --write .` を使う。

### CI でフォーマッタ未適用コードをエラーにする

- `prettier --check .` を使う。

## おまけ: ESLint + Prettier で全部 sort する

### TL;DR

- src: https://github.com/arx-8/try-separate-eslint-and-prettier/commit/f1f6ff803d6fefd2223cac384d284d9694807fbd

### sort 対象と package 名

| sort 対象                              | package 名                                             |
| -------------------------------------- | ------------------------------------------------------ |
| import 文                              | prettier-plugin-import-sort + import-sort-style-module |
| Object のキー                          | eslint-plugin-sort-keys-fix                            |
| Object destructuring assignment のキー | eslint-plugin-sort-destructure-keys                    |
| type/interface 宣言のキー              | eslint-plugin-typescript-sort-keys                     |

- これで「リーダブルなキーの並び順とは」とか悩む必要がなくなる。
- `eslint-plugin-simple-import-sort` ではなく `prettier-plugin-import-sort` を選択している理由は、prettier との相性のため。 `eslint-plugin-simple-import-sort` の方は、2 回保存しないと auto fix しきれないケースがある。
  - 恐らく prettier -> eslint の実行順になった場合に、 `eslint-plugin-simple-import-sort` による prettier 違反コードが生成されてしまう。
  - なんだかんだ `eslint-plugin-prettier` は合理的だったのではと思わんでもない。
- `organizeImports` では非 VSCode 民が救われないため、ぜひ `prettier-plugin-import-sort` がもっと普及してほしい。
【AWS SOA】ELBに関するログやメトリクスの備忘録

#はじめに
私はAWS SOAを勉強しています。SOAですとログやメトリクスについての問題の出題が多いため、今回はELBのログやメトリクスについて簡単にQ&A形式でまとめていきたいと思います。

#Q&A
Q.ロードバランサーのメトリクスを見たい時、どうするか？
A.EC2>ロードバランサー>モニタリングで、CloudWatchメトリクスを見ることができる。

![スクリーンショット 2020-10-18 17.31.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/76c83ef2-ff17-06c9-c8dd-5d49945e4825.png)

また「すべてのCloudWatchメトリクスを表示」をクリックすると、CloudWatchのメトリクスを見ることができる。そこでApplicationELBを選択すれば、詳細にELBのメトリクスを見ることが可能。
![スクリーンショット 2020-10-18 17.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/d8e1caca-5f24-58a2-3eb3-255bac15bc5d.png)

Q.ターゲットグループのメトリクスを見たい時、どうするか？
A.EC2>ターゲットグループ>モニタリングで、メトリクスを見ることが可能。
![スクリーンショット 2020-10-18 17.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/4173770a-83a4-5628-711c-87e5413fb577.png)

Q.ロードバランサーのアクセスログが取りたい時、どうするか？
A.EC2>ロードバランサー>説明>属性で、属性の編集を選択する。
![スクリーンショット 2020-10-18 17.48.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/563b1489-c696-a14a-1d13-f25a42c4883f.png)
S3の場所で任意の名前を入力する。この場所の作成にチェックをして保存する。
![スクリーンショット 2020-10-18 17.53.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/2a874e09-fc60-e11a-c8aa-ef6137f27b01.png)
S3に行き、ログができているか確認する。
![スクリーンショット 2020-10-18 17.56.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/c92d8f85-a2db-5eee-4459-8cd0fc464780.png)
該当の箇所まで行き、ダウンロードするとアクセスログが確認できる。
![スクリーンショット 2020-10-18 18.00.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/0d557036-8e63-5a7a-95a6-46c821a113c6.png)

ログの中身
・タイム
・クライアントIPアドレス
・遅延時間
・リクエストパス
・サーバーリスポンス
・トレースID
など

参考
Ultimate AWS Certified SysOps Administrator Associate 2020
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html
npx でパッケージ名とコマンドが異なる場合（npx -p <package> -c "<commond>"）


# npx -p <package> -c "commond"

例えば `express-generator` のパッケージでは使用するコマンドは `express` というように、パッケージ名とコマンドが異なる場合は `npx -p <package> -c "<commond>"` とします。

```shell
# express というコマンドは存在しないため失敗する
$ npx express --version
npx: 50個のパッケージを1.814秒でインストールしました。
コマンドが見つかりません： express

# -p で express-generator パッケージ、-c で express コマンドを指定すると実行できる
$ npx -p express-generator -c "express --version"
npx: 10個のパッケージを1.277秒でインストールしました。
4.16.1
```

ちなみに、挙動をみると `npx -p <package> -c "<commond>"` と実行する場合は、そのパッケージがローカルインストールされているのかどうかに関わらず、リモートのパッケージをインストールするみたいです。
ボタンの中のテキストを中心にする方法


```
.testbutton {
  display: inline-flex;
  align-items: center; 
　justify-content: space-around;
}
```

２行以上のテキストをDIVの中にvertical中心にするときは

```
display: flex;
    justify-content: center;
    align-content: center;
    flex-direction: column;
```

また、下記はzerosixthreeからのもので、6行のCSSで何でも中央に配置できます

```
p {
  text-align: center;
  position: relative;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
```
Prettierのおすすめ設定

![スクリーンショット 2019-03-10 12.44.19.png](https://qiita-image-store.s3.amazonaws.com/0/242655/70addf0e-bf76-3a02-63f4-81778dec26a8.png)

## Prettier とは
- [Prettier · Opinionated Code Formatter](https://prettier.io/)
- コードフォーマッタ (コード整形ツール)
- HTML, CSS, JavaScript, Markdown, YAML, GraphQLなどの言語に対応している (詳しくは[公式サイト](https://prettier.io/)参照)
- Atom, Emacs, Espresso, Sublime Text, Vim, Visual Studio, VS Code, WebStorm などのエディタでプラグインが提供されている(もちろんnodeのモジュールとして単体でも使える)
- 入門者向けにまとめたもの
    - [Prettier 入門](https://qiita.com/ohnaka0410/items/9681a1b193e002a05e3d)

## おすすめ設定
```javascript:/.prettierrc.js
/**
 * Prettier Configuration
 */
module.exports = {
  // デフォルト設定
  // printWidth: 80
  // tabWidth: 2,
  // useTabs: false,
  // semi: ture,
  // singleQuote: false,
  // quoteProps: "as-needed",
  // jsxSingleQuote: false,
  // trailingComma: "es5",
  // bracketSpacing: true,
  // arrowParens: "always",
  // rangeStart: 0,
  // rangeEnd: Infinity,
  // jsxBracketSameLine: false,
  // requirePragma: false,
  // insertPragma: false,
  // proseWrap: "preserve",
  // htmlWhitespaceSensitivity: "css",
  // vueIndentScriptAndStyle: false,
  // endOfLine: "lf",
  // embeddedLanguageFormatting: "auto"

  // 設定
  // printWidth: 120,
  // tabWidth: 2,
  // useTabs: false,
  semi: true,
  singleQuote: false,
  quoteProps: "as-needed",
  jsxSingleQuote: false,
  trailingComma: "es5",
  bracketSpacing: true,
  arrowParens: "always",
  rangeStart: 0,
  rangeEnd: Infinity,
  jsxBracketSameLine: false,
  requirePragma: false,
  insertPragma: false,
  proseWrap: "preserve",
  htmlWhitespaceSensitivity: "css",
  vueIndentScriptAndStyle: false,
  // endOfLine: "lf",
  embeddedLanguageFormatting: "auto"
}

```

### 補足
```javascript
  // 設定
  // printWidth: 120,
  // tabWidth: 2,
  // useTabs: false,
  // endOfLine: "lf",
```
この部分はEditorConfigで設定できるので、設定していません。
EditorConfigのおすすめ設定はこちら→[EditorConfigのおすすめ設定](https://qiita.com/ohnaka0410/items/89a059636e2e482e49fe)

その他の部分については、デフォルト設定のままですが、
これまでの更新履歴によると、デフォルト値が変わることがあるため、
明示的に書いておいたほうがいいと思います。
※保守時にバージョンアップで挙動が変わると大変なことに。。。:innocent:
EditorConfigのおすすめ設定

## EditorConfigとは :thinking:
- 様々なテキストファイルのコーディングスタイルを統一してくれるツール
    - インデントや文字コードなどを揃えることができる。
    - 複数人の開発だけでなく、後々保守などで別担当者が資産を触る場合もコーディングスタイルに迷わ無くてすむ。
- かなり他多様なエディタやIDEにバンドルされている。 [[公式サイト]](https://editorconfig.org/#download)


## おすすめ設定 :nerd:
```ini:/.editorconfig
# http://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
max_line_length = 120
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
max_line_length = 0
trim_trailing_whitespace = false

```

### 補足
```ini:
[*]
charset = utf-8
end_of_line = lf
```
最近のプロジェクトであればこの辺はスタンダードかなと。

```ini:
indent_size = 2
indent_style = space
```
ハードタブは細かい余白の調整ができなかったりするので、ソフトタブ(スペース)派です。

```ini:
max_line_length = 120
```
80だと少し短いので120にしてます。

```ini:
trim_trailing_whitespace = true
```
行末の余計なスペースは無駄なので削除します。

```ini:
insert_final_newline = true
```
なんとなくでやったけど、ちゃんと理由があるらしい。
[POSIXの仕様では「テキストファイルの末尾は改行(newline)で終わる」のが正しい、を確認してみた。](https://msfukui.hatenablog.com/entry/2018/12/18/071145)

```ini:
[*.md]
max_line_length = 0
trim_trailing_whitespace = false
```
Markdownは行の末尾のスペースや改行有無が出力結果に影響するので、EditorConfigで勝手に変更されないように。
whereメソッドを使って別のモデルの値を参考に絞り込みを行う。

#概要
whereメソッドを使った複数の条件の絞り込みを行ったのでまとめる。
##やりたいこと
productモデルが作成された時間の直前に作成されたdeveloperモデルの情報を一つ取得したい。
###前提条件
Product（製品）モデルとDeveloper（開発者）を作成。この２つのモデルは関連付けされていない。（ここはあえてです）
Developerモデルはどんな製品を作ったのかの情報（developed_product_number)を持っている。productには製品ナンバー(number)がついておりこの２つの値は等しい。
（だったら関連付けさせようよって話ですが今回はこの条件でいきます。）
同一の製品を作成した複数の開発者の中から製品ができる直前に作成された開発者の値を取得したい。

###実装

ではまず実際のコードを載せます。

```
product = Product.find(params[:id])


@Developer = Developer.where(developed_product_number: product.id).where('created_at < ?', product).order(created_at: :desc).limit(1) 
```

こんな感じです。解説いきます

```
product = Product.find(params[:id])
```


対象となるproductのIDを取得して変数productに代入。
ここで変数@Developerに条件をつけて絞り込み検索をした値を入れます。

```
@Developer = Developer.where(developed_product_number: product.id).where('created_at < ?', product).order(created_at: :desc).limit(1) 
```

部分的に分けます。

```
@Developer = Developer.where(developed_product_number: product.number)
```
ここでは先程取得した変数productのidを取得しています。

次に値を絞り込みます。

```
where('created_at < ?', product).order(created_at: :desc).limit(1) 
```
ここでproductが作成された時間より前に作成された複数の開発者の情報取得し、降順から数えて１つ目の開発者の情報を取得しました。
かなり長くなってしまったのでここのコードはスコープなどに切り分ける必要がありますね。
WordPressでJavaScriptが動かない時、もしかしたらこれが原因かも

![wordpress.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698437/f3c0f081-6f70-8f28-de85-59682ace39bb.jpeg)


『WordPress JavaScript 動かない』などで検索をすると大体

・そもそもJavaScriptが読み込まれているか確認しましょう
・ブラウザのキャッシュを削除しましょう

のような記事が出てくるのですが、これらだけでは解決しない場合があります

## JavaScriptが動作しない原因と解決策

functions.phpでJavaScriptを読み込む場合、下記のようなコードを書くと思います

```PHP:functions.php
wp_enqueue_script('sample, get_template_directory_uri().'/js/sample.js');
```

これだけでも読み込みはされているはずです。

検証ツールをみてみても読み込まれているのがわかると思います。

ただ読み込まれている場所が問題です

### 【原因】<head>内にJSが読み込まているから

<head>内にJavaScriptが読み込まれると、getElementByIdなどのHTMLを参照するコードが全てエラーになってしまいます

JavaScript→HTMLの順で読み込まれると、id(やclassなど)を取得できないからです

### 【解決策】JSを読み込む場所を指定する

したのように記述することで通常と同じように、

JavaScriptの読み込み場所を</body>直前にすることができます

```PHP:functions.php
wp_enqueue_script('sample', get_template_directory_uri().'/js/sample.js', array(), '1.0', true);
```

array()や1.0は関係ないですが、

最後の引数で、値をtrueにすることで、JavaScriptが</body>直前で読み込まれるので

HTML→JavaScriptの順で読み込まれ、id（やclass）を取得できるのでエラーになりません

## まとめ

WordPressでJavaScriptが動かない時に、やるべきこと

・そもそもJavaScriptが読み込まれているか確認しましょう
・ブラウザのキャッシュを削除しましょう

＋ wp_enqueue_scriptの第5引数をtrueにしましょう

以上です

この記事の内容が役に立ったという方がいましたら、[Twitter](https://twitter.com/YUNI_1016)でも情報発信をしていますので、フォローしていただけると嬉しいです
sha256ハッシュ値っぽい64桁ランダム英数字が流れるだけの疑似データ解析画面を表示するPowerShellスクリプト


#はじめに

エンジニアの仕事は理解されにくい。
理解されにくいから値切られる。
もう値切られたくない。でもどうすれば…

このコードは、そんな荒んだ心に魔が差したコーヒーブレイクのひとときに生まれました。



#使い方・想定

「パソコンの調子がおかしい気がするんだけどちょっと見てくれない？」などと、クライアントや社内の営業担当が言ってきた時がチャンス。

「分かりました。すぐ調べてみます。」と返事するやいなや、PowerShellを起動して下のコードをコピペ＆実行するだけ。

解析結果っぽい画面が流れていくのを眺めながら、「特におかしな所はなさそうですね...」等のセリフをはさめば、なんかすごい特別な技術でなんかすごいプログラムの解析ができるなんかすごい人感が醸し出せます。

#仕様

・PowerShwllが入っていればコピペするだけで動く、はず。

・下のコードはハッシュ値っぽい文字列を857行、約15秒かけて表示します。数を増やすと「解析に時間かかってる感」もプラスできます。


#コード
```analysis.ps1
for ($i=0; $i -lt 857; $i++){
  $sha = -join ((1..64) | %{(49..57) + (97..122) | Get-Random} | % {[char]$_})
  Write-Output ("output result "+$i+" : "+$sha+ "        next analyzing....... ")
}
Write-Output ("Success, this analysis has completed.")
```

#結果
![スクリーンショット 2020-10-18 17.48.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559502/609ab076-fd4f-ed0d-0cc9-3058a9b282fb.png)


#おわりに

このコードでなんかすごい人感が伝わることで、この世から理不尽に値切られるエンジニアが一人でも減りますように。
Windows 版 PHP で gRPC を使う

`XAMPP for Windows` の `PHP` に `gRPC` エクステンションをインストールしたときの手順メモ
今回はプリコンパイル済みの dll をダウンロードしてインストールした

# 検証環境

```
Windows10 Home Edition
XAMPP for Windows 7.4.9 (x64)
```

# PHP がスレッドセーフか確認

```
D:\>php --version
PHP 7.4.9 (cli) (built: Aug  4 2020 11:52:41) ( ZTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
    with Xdebug v2.8.1, Copyright (c) 2002-2019, by Derick Rethans

D:\>php -i | grep -i thread
Thread Safety => enabled
Thread API => Windows Threads
```

`XAMPP` に付属している `PHP` はスレッドセーフ

# gRPC エクステンションのセットアップ

## ダウンロード

下記のサイトから dll のアーカイブをダウンロードする
[PECL :: Package :: gRPC](https://pecl.php.net/package/gRPC)

2020-10-18 現在、最新の安定板は `1.32.0`
[PECL :: Package :: gRPC 1.32.0 for Windows](https://pecl.php.net/package/gRPC/1.32.0/windows)

`XAMPP` の `PHP` のバージョンは `7.4.9 ZTS x64` なので、`7.4 Thread Safe (TS) x64` をダウンロードする
![grpc_win_1.32.0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321059/7ba3154b-732e-2e5f-d980-dccd526be317.png)

## dll のインストール

ダウンロードしたファイルを解凍して `php_grpc.dll` を `\xampp\php\ext` にコピーする
`\xampp\php\php.ini` に下記を追加

```
extension=grpc
```

# 動作確認

```
D:\>php -i | grep -i grpc
grpc
grpc support => enabled
grpc module version => 1.32.0
grpc.enable_fork_support => 0 => 0
grpc.grpc_trace => no value => no value
grpc.grpc_verbosity => no value => no value
grpc.log_filename => no value => no value
grpc.poll_strategy => no value => no value
```

# 参考

- [gRPC for PHP のインストール  |  デベロッパー ツール  |  Google Cloud](https://cloud.google.com/php/grpc)
カスタムUIViewにて"loadNibNamed"のところで"EXC_BAD_ACCESS "

ちょっとだけ沼ったんで書いておきます。

## 起こった事件

![スクリーンショット 2020-10-18 17.34.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468821/ed4f71fa-4634-b3da-8d7a-8960dc066086.png)

カスタムUIViewを読み込もうとしたときに、`loadNibNamed`で`EXC_BAD_ACCESS`のエラー...



## 解決した方法
簡単に解決できました。

xib上のViewのCustom Classにクラスを指定していたことが間違いでした。
これを**File'sOwnerのCustom Class**に指定し直しましょう。

![スクリーンショット 2020-10-18 17.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468821/cad1f0dd-15ea-1824-6896-9769f365ba93.png)

Outlet接続等はViewのCustom Classにクラスを指定していてもうまくいくので気付きにくいなぁと思いました。

## 参考
[xibファイルのカスタムViewクラスが File's Owners に設定すること] (https://scrapbox.io/iOS-App-Development/xib%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0View%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%8C_File's_Owners_%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8)
俺的RxSwiftまとめ①

#RxSwiftとは
[RxSwift](https://github.com/ReactiveX/RxSwift)はReactive Extensions Swiftの略のこと。[Reactive Extensions](http://reactivex.io/)は非同期処理をいい感じに時系列に沿って処理してくれるC#の最強ライブラリ。

つまり、RxSwiftはSwiftに従来備わっている[非同期処理](https://qiita.com/kmnohno3/items/00d91b3cc13fb248e3cc)の書き方

- [デリゲートデザインパターン](https://qiita.com/nitaking/items/d441c5aa2aceaf4fc089)
- [Notificatin Center](https://qiita.com/ryo-ta/items/2b142361996657463e5f)を使った[オブザーバーパターン](https://qiita.com/tanakahisateru/items/61cf521f0fe462324f36)
- GCD([サクッとわかる用](https://qiita.com/ShoichiKuraoka/items/bb2a280688d29de3ff18))([一番詳しい記事はこっち](https://qiita.com/shiz/items/693241f41344a9df6d6f))
- [クロージャー](https://qiita.com/narukun/items/b1b6ec856aee42767694)
- [KVO](https://developer.apple.com/documentation/swift/cocoa_design_patterns/using_key-value_observing_in_swift)
- [PromiseKit](https://grandbig.github.io/blog/2018/04/24/swift-promisekit-2/)([Promiseの概念はこちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise))
- [Combine](https://dev.classmethod.jp/articles/swift-combine-framework-for-beginners/)

の仲間で、非同期処理をいい感じに行うための方法の一種です。

#RxSwiftの非同期処理方法
では、RxSwiftはどうやって非同期処理を行っているのか?
RxSwiftでは、様々なイベント/処理を、時間とともに流れてくる一連のデータ(データストリーミング)に対して実行します。([リアクティブプログラミングと呼ばれるもの](https://ninjinkun.hatenablog.com/entry/introrxja))

上記の利点として、

- プログラム内で発生する全てのイベントを時間軸で捉えることができる
- コールバック地獄に陥らない
- [MVVM](https://qiita.com/FuruyamaTakeshi/items/6c4404f1fd61e3fa4eb7)を導入することで、FatViewControllerからの脱却/テストしやすいコードを書ける([具体例1](https://qrunch.net/@iiinaiii/entries/IGUnRqkZiuDkTe8f),[具体例2](https://academy.realm.io/jp/posts/slug-max-alexander-mvvm-rxswift/))
- [関数型プログラミング](https://qiita.com/stkdev/items/5c021d4e5d54d56b927c)で書ける

というものがあります。
CentOS7におけるBonding設定のネットワークに802.1X認証をする

# 単体のNICでのネットワーク設定はうまくいくが...

導入したサーバのネットワークを複数のNICポートを使って**Bongingにして802.1Xの認証でネットワークに参加**してほしい案件がありました。
自分の力だけでは単体のNICによるネットワーク参加しかできませんでしたが、周りの人の協力もありBongingの場合でも802.1X認証で参加することができました。

ネット上で調べても「**Bonding設定**」での802.1X認証の方法が出てきませんでしたので、この場で記事にして公開しようと思います。(協力してくださった方々ありがとうございます！)

# 環境・用意するもの
サーバとネットワークスイッチの機器情報はお答えできませんが、サーバはラッキング形式の富士通やHP,IBMのようなサーバで、ネットワークスイッチはNETGEARやCiscoのような製品を使ってやっていると考えていただければと思います。
※あらかじめ、CentOS7内でネットワークのbonding設定を作っておく前提で話を進めます。

``` 環境
OS:CentOS7.8
BondingにするNICポート：Intel製10GNICにあるポート2つで有線による接続
証明書ファイル：ZZZZZZ.pem(またはcrt形式でも良い)
秘密鍵ファイル：ZZZZZZ.p12
```

# ① crt形式からpem形式に証明書ファイルを変換
当初はcrtファイル形式の証明書をユーザからいただいていたのですが、原因はわかりませんがcrt形式だとこの後の作業で802.1X認証が失敗してしまいました。
なので、crtからpem形式に以下のコマンドで変換します。
※証明書ファイルがpem形式のままでしたらこの作業は不要です。

```コマンドライン
openssl x509 -in ZZZZZZ.crt -out ZZZZZZ.pem
```

# ② 証明書ファイルと秘密鍵ファイルの保存場所ディレクトリを移行する
`/etc/pki/CA/certs/`にZZZZZZ.pemとZZZZZZ.p12を保存します。

# ③ ifcfgファイルの編集
bondingの設定ファイルは`/etc/sysconfig/network-scripts/ifcfg-bond0`にて以下のように設定を行いました。

```
BONDING_OPTS="mode=4 miimon=100 xmit_hash_policy=layer2+3"
DEVICE=bond0
TYPE=Bond
BOOTPROTO=none
BONDING_MASTER=yes
NAME=bond0
ONBOOT=yes
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
MTU=9000
DNS1=aaa.bbb.ccc.ddd
DNS2=aaa.bbb.ccc.ddd
GATEWAY=aaa.bbb.ccc.ddd
IPADDR=aaa.bbb.ccc.ddd
NETMASK=aaa.bbb.ccc.ddd
PREFIX=yy

# 802.1X認証設定
KEY_MGMT=IEEE8021X
IEEE_8021X_EAP_METHODS=TLS
IEEE_8021X_IDENTITY=XXXXXXXXX
IEEE_8021X_CA_CERT=/etc/pki/CA/certs/ZZZZZZ.pem # ②でpem形式ファイルを保存した先のパスを指定
IEEE_8021X_PRIVATE_KEY=/etc/pki/CA/certs/ZZZZZZ.p12 # ②でp12形式ファイルを保存した先のパスを指定
DOMAIN=zzzz.zzzz.zzzz
```

# ④ /etc/sysconfig/wpa_supplicantと/etc/wpa_supplicant/wpa_supplicant.confの編集
`/etc/wpa_supplicant/wpa_supplicant.conf`の内容を以下のように編集します。

```
INTERFACES="-iZZZZZZ"
DRIVERS="-Dwired"
OTHER_ARGS="-u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid -t"
```

`/etc/sysconfig/wpa_supplicant`の内容を以下のように編集します。

```
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
network={
        key_mgmt=IEEE8021X
        eap=tls
        identity="ZZZZZZ"
        ca_cert="/etc/pki/CA/certs/ZZZZZZ.pem"
        private_key="/etc/pki/CA/certs/ZZZZZZ.p12"
        private_key_passwd="ZZZZZZ"
        }
```

# ⑤ NetworkManagerをサーバ起動時に立ち上げを無効化
NetworkManagerがあらかじめ起動していると802.1X認証ができませんので、**サービスを無効化**します。

```
chkconfig NetworkManager off
```

# ⑥ wpa_supplicantを有効化・起動
802.1X認証のためにはwpa_supplicantが起動していないとダメなので**サービスの有効化と起動**をします。

```
chkconfig wpa_supplicant on
systemctl start wpa_supplicant
```

# ⑦ wpa_supplicantを起動してConnection成功するか確認する

以下のコマンドで`bond0: CTRL-EVENT-CONNECTED - Connection to <MACアドレス> completed`と出れば802.1Xの認証が成功できています。

```
wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -D wired -i bond0
```

# ⑧ ネットワークスイッチ側でSupplicantの認証が成功できているか確認
※ネットワークスイッチのメーカーや機器によってログの出方やコマンドも変わるため省略します。
LPIC Level1のためにVagrant+VirtualboxでUbuntuを仮想環境として構築した時の手順。

# 今更ながら

LPIC面白そうだし受けてみるか！ということでひとまず、

[1週間でLPICの基礎が学べる本 第3版 徹底攻略シリーズ](https://amzn.to/356c4Y5)

を読んで、

[Linux教科書 LPICレベル1 Version5.0対応](https://amzn.to/31d5u0D)

で出題範囲のインプットをしながら[ping-t](https://ping-t.com/)の問題を解いている最中です。

まぁ問題を暗記して解けるようにはなりそうだけど、少し問題の構造を変えられたら解けなくなりそうだし、動かさずに覚えるのは難しそうだと感じたので動かそう！という目的で構築しました。

何かしら前例があるだろうと思って検索してみると、以下のような動画で実際に同じような環境でCentOSを動かしていたので、Ubuntuを動かす場合の環境構築をしてみました。

[新入社員研修のプロが伝授！LPIC-1学習ポイント](https://www.youtube.com/watch?v=XE7nCqj115Y&t=479s)

# そもそもこれらは何？

## Virtualbox

### Virtualboxって何？

Oracleが管理しているOSSの仮想環境を構築するためのソフトです。

### 使うメリットはあるの？

じゃあ仮想環境を作ると何が嬉しいの？という疑問が生まれると思いますが、一つのOSの上で複数のOSを取り扱うことができるようになる、というものが一般的でしょう。
例えば、多くの場合、本番環境と開発環境は異なります。
必要なパッケージやOSによる差異など異なる要素は様々ですが、これらを実際にローカルの開発環境で動かしたい、となった時に使うものです。

また、仮想環境で何か致命的なミスを起こしたとしても、その環境が元のOSに影響を及ぼしたりすることはありません。
これらのメリットを享受するために仮想化が使われています。

## Vagrant

### Vagrantって何？

VMWareやVirtualboxとかの仮想化ソフトの操作を、代行してくれるソフトです。
今回はこれを使って構築することで本来必要なOS(Ubuntuのイメージのダウンロードなど)の操作をVagrantを通して管理ができるようになります。

### それは分かった。何のメリットがあるの？Virtualboxだけで良くない？

**vagrantfileに基づいた仮想環境の管理がコマンドでできるようになります。**

ありとあらゆる所でここのメリットは語られているのであまり深くは触れませんが、これこそがVagrantを使う大きなメリットの一つです。
チームメンバーなどと共有する時や、こういった記事形式で何か仮想環境を立てたい時に1からVMの構成を手順書などに書くのは面倒です。
それなら特定の構成を書いたファイルを取ってきて、コマンド叩いたら完成！の方が他のスピードも上がります。

~~あと個人的に勉強したかった~~



# 環境構築

## 環境

- OSX Catalina 10.15.7
- VBoxManage 6.0.14r133895
- Vagrant 2.2.10
- VirtualBox 6.1.14


## VirtualBox

[公式ページ](https://www.virtualbox.org/)からパッケージをダウンロードします。

インストールします。
VirtualBoxの設定はこれで終わりです。


## Vagrant

[公式ページ](https://www.vagrantup.com/)にアクセスし、Downloadをクリック。


それぞれのプラットフォームごとのバージョンがダウンロード可能になっているのでダウンロード。

ダウンロードしたパッケージをインストール。


すると無事にインストールができているはずなのでターミナルで以下のように進める。


```terminal
# ディレクトリ作成と移動
$ mkdir Ubuntu && cd Ubuntu

# Vagrantにインストールされているリストの確認
# 恐らく何もないよ！とでます
$ vagrant box list

# フォルダ内にUbuntuのvagrantfileのダウンロード、及びプロビジョニング開始
$ vagrant init ubuntu/trusty64
$ vagrant up

# ubuntu/trusty64 (virtualbox, 20190514.0.0)
$ vagrant box list

# 以下のコマンドでポート情報などが出るのでここでの情報を元にログインする
$ vagrant ssh-config

# sshログインする
# user,passwordは共にvagrant
$ ssh -p 2222 vagrant@localhost
```
これで実はUbuntuをターミナル上で動かせます。
事実Virtualboxを見てみると以下のように仮想環境が動いています。

これで実際にコマンドを入力して楽しめます。
やったね！


では、お疲れ様でした。
JavaScriptの型判定

####型判定について調べることがあったので、まとめてみました。

#先に結論から
型判定には`Object.prototype.toString.call()`を使うと幸せになれる。

#型の種類
JavaScriptは動的型付け言語のため、静的型付け言語のような**変数の型**はありません。
しかし、文字列や真偽値のような**値の型**は存在します。

この**値の型**は**データ型**と呼ばれ、大きく分けて下記の２つに分類されます。

##プリミティブ型（基本型）
 - Boolean（真偽値）
  - `true`と`false`の２つがある
 - String（文字列）
  - `"あいうえお"`などのテキストデータ
 - Number（数値）
  - `42` や `3.14159` などの数値のデータ
 - null
  - 値が存在しないことを意味する。`null`の１種類しかない
 - undefined
  - 値が未定義であることを意味する
 - Symbol
  - ES2015から追加された一意で不変な値を意味する（正直使い所がよくわかっていない。。）
 - BigInt（巨大な整数）
  - ES2020から追加された`9007199254740992n`などの任意の精度で精度で表すことができる（正直使い所がよくわかっていない。。）

##オブジェクト型（複合型）
- プリミティブ型以外のデータ
 - オブジェクト、配列　関数、正規表現、Dateなど

#型判定してみる
`typeof`演算子を使うと型を調べることができる

```js
console.log(typeof true); // boolean
console.log(typeof "あいうえお"); // string
console.log(typeof 1234); // number
console.log(typeof null); // object （なぜ？！？！）
console.log(typeof undefined); // undefined
console.log(typeof Symbol("シンボル"));// symbol
console.log(typeof 9007199254740992n); // bigint
console.log(typeof ["hoge", "fuga"]); // object （なぜ？！？！）
console.log(typeof { "key": "value" }); // object
console.log(typeof function() {}); // function
console.log(typeof(new Date())); // object （なぜ？！？！）
console.log(typeof(new Array())); // object （なぜ？！？！）
```
##`typeof`では厳密な判定が出来ない問題
判定結果を見ると、`null`や配列や`new`した際に`object`として判定されてしまう。。。。
これでは細かなオブジェクト型の判定はできなく、配列/null/日付等の区別もできない:fearful:


ちなみに、`typeof null`が`object`と判定されてしまうのは、歴史的経緯のある仕様のバグ[^1]らしい（初めて知った）

##Object.prototype.toString.call() を使って厳格な型判定をする

```js
const toString = Object.prototype.toString;

console.log(toString.call(true)); // [object Boolean]
console.log(toString.call("あいうえお")); // [object String]
console.log(toString.call(1234)); // [object Number]
console.log(toString.call(undefined)); // [object Undefined]
console.log(toString.call(Symbol("シンボル"))); // [object Symbol]
console.log(toString.call(9007199254740992n)); // [object BigInt]
console.log(toString.call(["hoge", "fuga"])); // [object Array]
console.log(toString.call({ "key": "value" })); // [object Object]
console.log(toString.call(function() {})); // [object Function]
console.log(toString.call(new Date())); // [object Date]
console.log(toString.call(new Array())); // [object Array]
```


[^1]: JavaScriptが最初にNetscapeで実装された際にtypeof null === "object"となるバグがありました。このバグを修正するとすでにこの挙動に依存しているコードが壊れるため、修正が見送られ現在の挙動が仕様となりました。 詳しくは https://2ality.com/2013/10/typeof-null.html 参照。
[Unity]Unity Recorderをインストールしよう(2020)

今現在、AssetStoreから消えていてインストールできませんでした。

PackageManagerにあるのでそこからインストールします

Window -> Package Manager -> 右上の歯車から設定画面を開きます

そこの `Enable Preview Packages` にチェック。これで開発途中のパッケージがでてくるようになります。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/17746382-d49b-a05f-3bbc-1282a286fabe.png)

Unity Recorderを探してインストール

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/3b110913-0fab-c78a-5d88-e8b66c5911ed.png)
VBAでサブフォルダ内のExcelファイルをマージする


#Excelに
Excelにモジュールを追加して下記のソースを添付してください。

```
'パブリック変数
Public gSheet As Worksheet
Public gRow As Long
'定数
Const C_GET_ROW_S As Long = 4 '取得元データの開始行
Const C_SET_ROW_S As Long = 3 '添付先データの開始行

'サブフォルダを含むフォルダ内のファイルデータを取得する
Sub getFileData()
    With Application
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlCalculationManual
    End With
    
    '初期設定
    gRow = C_SET_ROW_S
    
    Set gSheet = Sheets(1)

    '初期化
    'A～K列まで初期化
    gSheet.Range("A" & C_GET_ROW_S & ":K" & gSheet.Range("A" & Rows.Count).End(xlUp).row).ClearContents
    
    'ファイルマージ
    Dim path As String
    path = "C:\work"
    'path = gSheet.Range("B1").Value
    Call mergeData(path)
    
    With Application
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlCalculationManual
    End With

End Sub

'サブフォルダも含むフォルダ内のファイルデータを探してデータをマージする
Sub mergeData(folderPath As Variant)
    
    '参照設定
    Dim fso As Object, folder As Variant, file As Variant
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    'フォルダ内のサブフォルダを探す
    For Each folder In fso.GetFolder(folderPath).SubFolders
        Call mergeData(folder)
    Next
   
    Dim row As Long
    'フォルダ内のファイルを探索
    For Each file In fso.GetFolder(folderPath).Files
        'エクセル以外は対象外
        If Not (LCase(fso.GetExtensionName(file)) Like "xls*") Then
            GoTo Continue
        End If
        
        gRow = gRow + 1
        row = gRow
        
        'ファイル内のデータをコピーする
        copyData (file)
       
        With gSheet
            'ファイル情報
            .Cells(row, 1) = folderPath 'フォルダパス
            .Cells(row, 2) = file 'ファイルパス
            .Cells(row, 3) = fso.GetFileName(file) 'ファイル名
            .Cells(row, 4) = fso.GetExtensionName(file) '拡張子
            .Cells(row, 5) = fso.GetFile(file).Size 'ファイルサイズ
            .Cells(row, 6) = fso.GetFile(file).DateCreated '作成日時
            .Cells(row, 7) = fso.GetFile(file).DateLastModified '最終更新日時
            .Cells(row, 8) = fso.GetFile(file).DateLastAccessed '最終アクセス日時
            
            'データ行数分ファイル情報をコピー
            .Range("A" & row & ":H" & row).Copy
            .Range("A" & (row + 1) & ":H" & gRow).PasteSpecial xlPasteValuesAndNumberFormats
        End With
        
Continue:
    Next
    
End Sub

'データコピーを行う
Sub copyData(filePath As Variant)
    
    Dim rowEnd As Long
    
    'データの範囲はB～D列
    With Workbooks.Open(filePath)
        rowEnd = .Worksheets(1).Range("B" & Rows.Count).End(xlUp).row
        '先頭行から末尾行までコピー
        .Worksheets(1).Range("B" & C_GET_ROW_S & ":D" & rowEnd).Copy
        'このブックの1シート目へ値貼り付け
        gSheet.Cells(gRow, 9).PasteSpecial xlPasteValuesAndNumberFormats
        'コピー中状態を解除
        Application.CutCopyMode = False
        'ブックを保存せずに閉じる
        .Close False
    End With
    
    'データ行数分追加
    gRow = gRow + rowEnd - C_GET_ROW_S
    
End Sub
```
ディープラーニングによる動画フレーム補間 Part1【Python】

大学で**ディープラーニングによる動画のフレーム補間**を扱っており、その過程で試している実装をアウトプットします。
これからも動画のフレーム補間の実装の続きを投稿していくので、もしよければLGTM＆フォローお願いします。

今回やったことは、実際の動画フレームを用いて前後６フレームから中間１フレームを生成するネットワークの構築です。

# 実装環境
Google Colab
https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja

# 実装概要
**前後フレーム（前３・後３）から中間フレームを生成するディープラーニング。**ネットワークはDnCNN[1]です。手近にこのネットワークがあったので使用しています。
（[1] Kai Zhang, Wangmeng Zuo, Yunjin Chen, Deyu Meng, and Lei Zhang, “Beyond a Gaussian Denoiser: Residual Learning of Deep CNN for Image Denoising”, https://arxiv.org/abs/1608.03981）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/26ec7863-87d7-9303-2ce1-e75eb3b0065f.png)

DnCNNのネットワークは次の通りです。本来はノイズ除去を目的としたものです。
入力について、フレームサイズは160*90、チャネル数は18チャネル（6フレーム*RBG）です。
出力について、フレームサイズは同様で、チャネル数は3チャネルです。

青色の中間層のパラメータをいじりました。
層数15、カーネルサイズ3*3、チャネル数72となっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/3dacd68a-5e7c-9564-ce3c-01f6381eef7c.png)

# データセット
街を撮影したMOT17を使いました。
https://motchallenge.net/
セット数は、train 1320, test 1285 です。

# 結果
１つ目の画像は、上から前２フレーム、生成した中間フレーム、後２フレームとなります。実際にはもう１フレームずつ入力がありますが、画像が小さくなってしまうので省略しました。

![no5-2_series.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/d6ceb3bf-6ff5-a701-4d37-5c80e9748579.png)

次の画像は、正解の中間フレームとの比較です。

![no5-2_midonly.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/cbb59b2a-09b4-4965-467e-4f08e5256094.png)

前後に引っ張られていたり、色が変化していたりと、補間できているとは全然言えない結果ですね。

# 性能評価
汎化性能のグラフはこちら。近い値を取っているので、ここは問題ないと思われる。
![no5-1_hanka.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/77db3dd0-fbd4-10fe-bd80-c5c4e1ec7fea.png)
損失値等の数値データはこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/52bfb7dc-a0a7-7979-4725-93b818aa4f33.png)

数値上、そこまで悪い値ではない印象です。以前に１画像をトリミングして疑似的なフレーム補間を行ったときの損失値と平均PSNRに近いです。しかし、これは前後画像がほぼ同じ画像であるためと思われます。mid-top rateは低くなっているので、ここを上げる必要があります。

# 考察
補間できていない理由として、
・データセット数の少なさ
・入力６フレームがうまく機能していない
・ネットワーク（DnCNN）の問題
の３点だと考えています。

訓練・テストデータともに1300セットほどです。元の画像数は多いのですが、１セットで７フレーム消費するのでなかなか量が稼げないです。自作データセットを今作っている最中なので、データセット数に気を付けながら進めたいと思います。

入力６フレームはどうなのでしょうか。。どの論文見ても前後２フレームで補間を行っているので、このまま６フレームでやり続けてうまくいくのか心配です。比較のためにも２フレームに戻したほうがいいと思い始めました。

# 今後の方針
・自作データセットでセット数を増やす。
　※ハイスピードカメラによるデータセット。このデータセットを使って精度が向上するかが研究の目的です。
・入力フレーム数を何枚にするか検証。
・別のネットワークでの検証。

# 最後に
最後まで読んでいただきありがとうございました。
改善点等ありましたら遠慮なくご指摘ください。
これからもこの系統の投稿をしていくので、よければLGTM＆フォローお願いします！
データベースになくても、データとして扱える活動的なハッシュ

#はじめに
　アンケートなんかでよく見かける、都道府県をプルダウンから選択させる機能。、form_withメソッドを使用して投稿する機能をもたせることができる。しかし、その都道府県はテーブル上では数値で管理されている方が使い勝手がよい。数値で管理できるようにするには、予め、都道府県名とそれに紐づく数字を用意しておく必要がある。そのようなときに便利な機能が、ActiveHashである。

##ActiveHashとは
　基本的に変更することのないデータをモデル内に記入することで、データベースへ保存せずにデータを取り扱うことができるようになるGem。主に、ビューで、プルダウンメニューとして表示させたいときに使う。

公式ドキュメントは[こちら](https://github.com/zilkey/active_hash)

##準備の流れ
1.　Gemの記述
2.　Gemをインストール
3.　モデルを生成

###1.　Gemの記述

ファイルのいちばん下の行でOK 

```ruby:Gemfile
gem 'active_hash'
```


###2.　Gemをインストール

```bash
% bundle install
```


###3.　モデルを生成

```bash
% rails g model モデル名 --skip-migration
```

モデル名には、プルダウンメニューを一括りにするような名前が望ましい。
ex)野球、サッカー、テニス…
　　　　　　　　のようなプルダウンを作成する場合は、モデル名は`sport`となる。


`--skip-migrationオプション`をつけることで、マイグレーションファイルを生成しなくなる。ActiveHashはデータベースに保存しないので、マイグレーションファイルを必要としない。

以後、スポーツのプルダウンメニューを例に説明する。

##記述から表示までの流れ
4.　クラスを定義し継承する
5.　プルダウンメニューの項目を記述
6.　アソシエーションを記述
7.　バリデーションを記述
8.　プルダウンメニューを表示

###4.　クラスを定義し継承する

「３.　モデル生成」で作られたモデルを以下の記述に変更する。

```ruby:app/models/sport.rb
class Sport < ActiveHash::Base
  self.data = []
end
```

ActiveHash::Baseを継承することで、ActiveRecordのメソッドが使用できる。

###5.　プルダウンメニューの項目を記述

プルダウンの中身は、配列にハッシュで入れる。

```ruby:app/models/sport.rb
class Sport < ActiveHash::Base
  self.data = [
    { id: 1, name: '---' },
    { id: 2, name: 'Baseball' },
    { id: 3, name: 'Soccer' },
    { id: 4, name: 'Tennis' }
  ]
end
```


###6.　アソシエーションを記述

以下、すでに、別の投稿したものを保存するテーブルが存在する前提の説明。

```ruby:app/models/post.rb
class Post < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
    belongs_to_active_hash :sport
end
```
`extend ActiveHash::Associations::ActiveRecordExtensions`の記述によって、`  belongs_to_active_hashメソッド`が使えるようになる。

sportモデルにアソシエーションの記述の必要はない。

<font color=red>※通常のアソシエーションと記述が異なる点に注意</font>

###7.　バリデーションを記述
```ruby:app/models/post.rb
class Post < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
    belongs_to_active_hash :sport

  validates :sport_id, presence: true #空の投稿を保存できない

  
  validates :sport_id, numericality: { other_than: 1 } 
                        #プルダウンの選択が「--」の時は保存できない
end
```

###8.　プルダウンメニューを表示

####collection_selectメソッド

```ruby

collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション)
```

```ruby
collection_select(:sport_id, Sport.all, :id, :name, {}, {class:"sport-select"})
```

保存されるカラム名：テーブルのどのカラムに保存をするのか。
オブジェクトの配列：配列のハッシュ全て表示させる場合は、`.all`でOK
カラムに保存される項目：`app/models/sport.rb`の中で、`id:`としていた部分を、カラムに保存させたい
選択肢に表示されるカラム名：プルダウンで`app/models/sport.rb`の`name:`としていた部分を表示させる
オプション：必要に応じて
htmlオプション：クラス名など

##最後に
　とにかく、collection_selectメソッドの引数が多すぎて、混乱しそう…