OmniAICreator/Qiita-1.07M huggingface dataset:
Splunk Table colorと閾値の関係

ダッシュボードを作る時に、SPLの`eval`とtable表示のときの色の閾値の関連がわかりづらいので忘備録として

reference:https://docs.splunk.com/Documentation/Splunk/latest/Viz/TableFormatsXML

#ダッシュボード
```xml:table
<dashboard>
  <label>table color test</label>
  <row>
    <panel>
      <table>
        <search>
          <query>| makeresults count=30
| streamstats count as delta
| eval delta = delta - 20
| eval colormap=case(delta &lt; -10,"red", -5 &gt; delta AND delta &gt;=-10,"orange", delta &lt; 0 AND delta &gt;= -5,"yellow", delta &gt;= 0 AND delta &lt; 5,"white",delta &gt;= 5, "green")</query>
          <earliest>0</earliest>
          <sampleRatio>1</sampleRatio>
        </search>
        <option name="count">40</option>
        <format type="color" field="delta">
          <colorPalette type="list">[#DC4E41,#FFA500,#FFFF00,#FFFFFF,#00FF00]</colorPalette>
          <scale type="threshold">-10,-5,0,5</scale>
        </format>
      </table>
    </panel>
  </row>
</dashboard>
```
#SPL
```java:spl
| makeresults count=30
| streamstats count as delta
| eval delta = delta - 20
| eval colormap=case(delta < -10,"red", -5 > delta AND delta >=-10,"orange", delta < 0 AND delta >= -5,"yellow", delta >= 0 AND delta < 5,"white",delta >= 5, "green")
```
#colorpalette
```xml:colorpalette
        <format type="color" field="delta">
          <colorPalette type="list">[#DC4E41,#FFA500,#FFFF00,#FFFFFF,#00FF00]</colorPalette>
          <scale type="threshold">-10,-5,0,5</scale>
        </format>
```
#一覧表
|case|例|color|閾値|palette|
|:-:|:-:|:-:|:-:|:-:|
|X < -10|-11,-12|red|-|#DC4E41|
| -10<= X < -5|-10,-5|orange|-10|#FFA500|
| -5 <= X < 0|-2,-1|yellow|-5|#FFFF00|
| 0 <= X < 5| 0,2|white|0|#FFFFFF|
| 5 <= X | 5,7 | green|5|#00FF00|
閾値が**以上**ということがわかる
#まとめ
Splunkのバージョンが8以上だと、[ifだけでなくcase](https://docs.splunk.com/Documentation/Splunk/8.0.3/Viz/TableFormatsXML#Color_palette_types_and_options)も使える。
[Splunk>Answersの例](https://answers.splunk.com/answers/820403/how-to-change-font-color-based-on-a-condition-for.html)
ただ、別なフィールドの値で判定とかできないような感じです。
数字の範囲の場合、SimpleXMLの場合は`以上`、GUIでやるときには左の値`以上`と認識していれば大丈夫だと思います。
IQ Bot：マッピング設定のやりかた　フォームフィールド（基本）

この記事では、IQ Botの事前設定のメインとなるマッピング設定のうち、フォームフィールドのマッピングのやりかたをまとめます。

フォームフィールドとテーブルフィールドの違いについては[こちらの記事](https://qiita.com/IQBotter/items/03063d0cb5412db47d46)をご参照ください。

#マッピングの基本的な考え方

##ラベルに対して、値がどこにあるかを教えてあげる

マッピングの基本的な考え方は、ラベルに対して値がどこにあるかを教えてあげることです。

###ラベルとは？　値とは？

下図のとおり、「ラベル」とは帳票上の項目の名称のことで、「値」はその中身です。

![101_ラベルと値とは.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/0479f290-5e27-f2a3-ba8d-bdc5dddd5557.jpeg)

###IQ Botの実際の画面

IQ Botの画面では以下のように、該当項目に対するラベルと値の場所をIQ Botに教えてあげます。

![ラベルと値の考え方.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/1563c764-5d27-4296-cbff-b6a5854b2136.jpeg)

###IQ Botによる自動取得

実際には、画面を開いた時点でIQ Botがラベルと値の場所を自動で取得できているケースもあります。

![操作不要のパターン.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/8f69ddc3-0d08-8f9c-9b62-4e419a7993cb.jpeg)

自動取得されたラベルと値の位置関係が正しい場合は、人間による操作は原則不要です。
（原則に該当しないパターンもあるのですが……ややこしいのでこちらは別途記事を書きます。）

自動取得の結果が間違っていた場合や、自動取得ができていなかった場合には人間が学習させてあげる必要が出てきます。
そのやりかたを次にまとめます。

#ラベルの位置を教えてあげる

まず、ラベルの位置を教えてあげます。

##ラベルの場所を指定するには

ラベルの場所は、こちら↓の要領で学習させます。
![マッピング学習（フィールド）.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/6d8d4538-6bd7-9c4a-7a9e-6d82dc5aeee0.gif)

筆者の経験上、IQ Botの操作に慣れていない人が間違いやすいポイントは以下です。
![ラベル_間違いやすいポイント.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/baa2df01-eefe-ddd9-4e11-92fa36d3ce19.jpeg)

ラベルを学習させるときは必ず「フィールドラベル」にカーソルを合わせた状態（＝黄枠になった状態）で帳票イメージからラベルを選択する必要があるので注意してください。

##ラベルの指定をやりなおすには

自動取得したラベルが間違っていたり、自分で一度設定したラベルの場所を変える場合のやりかたは以下のとおりです。

![マッピング学習の取り消し.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/b06a459f-9013-100c-9271-2bad15f9c28c.gif)

#値の位置を教えてあげる

##値の学習方法の基本

ラベルの位置を決めたら、次は値の位置を教えてあげます。
今度はラベルのときとは逆に、「フィールド値」の欄にカーソルを合わせた状態で、帳票上の値の位置をドラッグします。

![値の学習.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d5eb1eb9-1ac5-33ef-73f9-dcb70faa8d71.gif)

値の学習をやり直したいときは、「Draw」ボタンを押して何度でも学習をやり直すことができます。

##Drawボタンがない？！

バージョンによっては、「フィールド値」の横に「Draw」ボタンがない場合もあります。
その場合は、「フィールド値」の欄にカーソルを合わせて黄枠にした状態で、該当する値の場所をドラッグすればOKです。


#こんなときどうする？（応用編）

上記のやりかたがマッピングの基本のやりかたですが、実際に業務で処理する帳票を設定していると、「こんなときはどうするの？」という疑問が色々と出てくるかと思います。

以下、状況に応じた設定のやりかたを順次公開していきます。

- [ラベルと値がくっついている場合](https://qiita.com/IQBotter/items/2c4e6465c885009283a9)
- [ラベルがない項目の取得方法](https://qiita.com/IQBotter/items/9082c2b262004694bada)
- [ラベルの読取が不安定な項目の場合（ラベルが文字化けしやすい等）](https://qiita.com/IQ_Bocchi/items/958e9d7be938eb486a0b)
- 読み取った値の一部だけをデータ化したい場合（準備中）
Covid-19のソーシャル分析その１取得から可視化

##RでSNS分析
Twitterの分析をする必要が出てきたため
備忘録のため記述。

##データ取得から可視化まで
```R:filename.rb
#ライブラリー
library("twitteR")
library("lubridate")
library("ggplot2")
library("ggmap")
library("stringr")
library("tm")
library("RColorBrewer")
library("wordcloud")
#APIkey入力・認証
#参考：https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/
APIKey <- ""
APISecret <- ""
accessToken <- ""
accessSecret <- ""
options(httr_oauth_cache = TRUE)
setup_twitter_oauth(APIKey, APISecret, accessToken, accessSecret)
#ツイート取得
tw.Covid = searchTwitter("Covid-19", n=500)
#データフレーム化・変換
trendingTweets.df <- twListToDF(tw.Covid)
trendingTweets.df$text <- sapply(trendingTweets.df$text,
                                 function(x)iconv(x, to = "UTF-8"))
trendingTweets.df$created <- ymd_hms(trendingTweets.df$created)
#時間ごとにプロット
ggplot(data = trendingTweets.df, aes(x = created))+
  geom_histogram(aes(fill = ..count..))+
  theme(legend.position = "none")+
  xlab("Time")+ ylab("Number of tweets") +
  scale_fill_gradient(low = "midnightblue", high ="aquamarine4")
#国特定関数#
mapCountry <- function(x) {
  if(!is.na(str_match(tolower(x),"japan")) |!is.na(str_match(tolower(x),"fukushima")) ){
    "japan"
  }else if(!is.na(str_match(tolower(x),"new zealand")) |!is.na(str_match(tolower(x),"nz"))){
    "new zealand"
  }else if(!is.na(str_match(tolower(x),"india"))){
    "india"
  }else if(!is.na(str_match(tolower(x),"italy")) |!is.na(str_match(tolower(x),"italia"))){
    "italy"
  }else if(!is.na(str_match(tolower(x),"spain"))){
    "spain"
  }else if(!is.na(str_match(tolower(x),"mexico"))){
    "mexico"
  }else if(!is.na(str_match(tolower(x),"philippine"))){
    "philippines"
  }else if(!is.na(str_match(tolower(x),"china"))){
    "china"
  }else if(!is.na(str_match(tolower(x),"korea"))){
    "korea"
  }else if(!is.na(str_match(tolower(x),"indonesia"))){
    "indonesia"
  }else if(!is.na(str_match(tolower(x),"argentina"))){
    "argentina"
  }else if(!is.na(str_match(tolower(x),"unitedstates"))|!is.na(str_match(tolower(x),"united states"))){
    "US"
  }else {
    "rest_of_the_world"
  }
}


#トレンド特定
trendingTweets.df$covid_country <- sapply(trendingTweets.df$text,mapCountry)
#登場国可視化
ggplot(subset(trendingTweets.df,covid_country != 'rest_of_the_world'), aes(covid_country)) +
  geom_bar(fill = "aquamarine4") + 
  theme(legend.position="none", axis.title.x = element_blank()) +
  ylab("Number of tweets") + 
  ggtitle("Tweets by Country") 

```
##アプトプット
![each_country.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182397/fb890923-d819-ab8a-b741-2b3994e86438.png)
Twitterに位置情報が付加されていなくともある程度どこの国
から発信されたかわかるようになります。
##参考文献
2020年度版 Twitter API利用申請の例文からAPIキーの取得まで詳しく解説
https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/
正規表現でファイル名を一括置換

環境 windows10 bash

## やりたかったこと
hogehoge_Ch1_L1～L20.pdf のファイルリストから
hogehoge_Ch1_L8～L14-2.pdf のファイル名の Ch1を Ch2に置換

## find
対象ファイルを正規表現でリストアップしてみる。
正規表現の () | {} にエスケープが必要なようで不便なので regextype は posix-egrep を指定。

```
$ find . -regextype posix-egrep -regex '.*L(8|9|10|11|12|13|14).*'
./hogehoge_Ch1_L10.pdf
./hogehoge_Ch1_L11.pdf
./hogehoge_Ch1_L12.pdf
./hogehoge_Ch1_L13.pdf
./hogehoge_Ch1_L14-1.pdf
./hogehoge_Ch1_L14-2.pdf
./hogehoge_Ch1_L8.pdf
./hogehoge_Ch1_L9.pdf
```

## sed

findした結果をsedコマンドで置換してリネーム

```
$ find . -regextype posix-egrep -regex '.*L(8|9|10|11|12|13|14).*' | sed 'p;s/Ch1/Ch2/' | xargs -n2 mv
```

## 参考
- [正規表現に合致するファイル名をfindする方法](https://www.greptips.com/posts/301/)
- [[find,sed,xargs mv] ディレクトリ/ファイルの名前一括変更](http://171rr.blog.fc2.com/blog-entry-31.html)
- [Linuxで複数ファイルのファイル名の中の複数の箇所の文字列を任意の文字列に変換する方法](http://wisdomtrees.net/?p=629)
Gitにpush中に止まる！コミットするデータのサイズが原因かも？

Rails6.0でローカル開発環境を構築していたところ、
各種Gemの悪さを処理して、[こちらのサイト](https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39)を参考に進め、
ようやくたどり着いたGitへの初pushでまさかの停滞！

エラーが出るまでの経緯も含めてまとめました


##今回出たエラーがこちら


```
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 60
fatal: the remote end hung up unexpectedly
```
結論から言うと、このエラーが出たらコミットするデータのサイズが大きいので、
バッファが足りてないよ。ということらしいです。




##開発環境
OS: 64bit Mac macOS Catalina 10.15.3
Ruby 2.6.3
Rails6.0




##最初に起きた問題


いつものように、

```
$ git init
$ git add -A
$ git commit -m "first commit"
$ git remote add origin https://github.com/Gitユーザー名/リポジトリ名/git
$ git push -u origin master
```

とすると、

```
$ git push -u origin master
Enumerating objects: 6877, done.
Counting objects: 100% (6877/6877), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6430/6430), done.
Writing objects: 1% (26/6877), 26.57 MiB |〜
```

といった感じで、Writing objectsの箇所で静止しました。




##調べて分かったこと


調べていると、どうやら一度にコミットするデータのサイズが大きすぎるとプッシュ中に止まってしまうようだと分かりました。

100MB超えだと弾かれるそうなので、100MB以上のデータをコミットする方は[こちらの記事](https://qiita.com/kaneshin/items/0d19fc1cd86f931dc855)のように、削減の必要があると思います。

しかし、僕のは26.57MiBと書いてあるので全然軽いはず…

同様に「Git　push 容量」などと調べていくと、[こちら](https://stackoverflow.com/questions/24952683/git-push-error-rpc-failed-result-56-http-code-200-fatal-the-remote-end-hun/36843260#36843260)や[こちら](https://tree-tree-diary.hatenablog.com/entry/2018/09/26/012254)に遭遇。

どうやらこのコードを書くとGitのバッファの上限値を指定できるらしい。




##やったこと

とにかく打ってみた。

```
$ git config http.postBuffer 524288000
```
↑これだとバッファの容量が524288000Bits（62.50MB）

今回プッシュしたいデータは26.57MiB（27.86MB）なので、以下でも良いと思います。

```
$ git config --global postBuffer 32M
```




##それでも止まった


大抵の人はここまででプッシュできるはずです。

```
% git push -u origin master
Enumerating objects: 6877, done.
Counting objects: 100% (6877/6877), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6430/6430), done.
Writing objects: 100% (6877/6877), 26.57 MiB | 16.19 MiB/s, done.
Total 6877 (delta 793), reused 0 (delta 0)
```

この状態で15〜30分フリーズするようになりました。
一応Writing objectsのアップロードは終わってるみたいだし、進歩はしたかな笑

その後、冒頭のエラーが出ました。




##念のため確認したこと


さきほどのバッファの容量をさらに上げて試しました。




しかし、状況変わらず…
以下のコードで、バッファの上限が変更されているか確認。

```
$ git config --global --list
user.name=Sugeno
user.email=〜〜〜@gmail.com
sendpack.sideband=false
http.postbuffer=32M
```



念には念を

```
$ cd ~
$ vi .config
```

でgitconfigの中身を確認し、http.postbuffer=32Mであることをチェック。viエディタの使用法は[こちら](https://prev.net-newbie.com/linux/commands/vi.html)をチェック。

操作手順としては、「$ vi .config」後にバッファの値確認→指定した値になってれば「:wq→Enter」。

泣きの一回！

```
$ git push -u origin master
```

```
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 60
fatal: the remote end hung up unexpectedly
```

なんでや…万策尽きた…




##結果

一晩寝かせて、
・最初からアプリを見直すか
・クラウドIDE（Cloud9）
・Webサイト（二日前にデプロイしたもの）がプッシュできるか
を試してみようと思いましたが、

Twitterを見ているとプロキシを通すとプッシュできないと言っている方がいたので、自宅の固定回線ではなくスマホのテザリングでリトライしてみました。

なんと、すんなりプッシュできました笑

やはり回線の強弱やセキュリティ的要素も関係しているのかもしれません。
とはいえ、バッファの上限を上げる対策は間違いなく効いていたと思います。

少しでも参考になれば幸いです。
[Elasticsearch] 複数インデックスへの検索


Elasticsearch導入時にインデックス設計段階にて下記を確認したかったので、確認した内容。

* Elasticsearchにて複数インデックスへの検索ができるか？
* できるなら、そのやり方は。
* レスポンスのデータ構造がどうなるか
* 設計段階での注意点は何か

## version

* elasticsearch:7.6.2
* kibana:7.6.2

## 実行の流れ

Kibana の Consoleで実行していく。

### テストデータ投入

```kibana
# テストデータをmessagesインデックスに入れる
POST /messages/_doc/
{
  "properties":{
    "channel_id": 4,
    "content": "トルトル"
  }
}

# テストデータをtitlesインデックスに入れる
POST /titles/_doc/
{
  "properties":{
    "channel_id": 1,
    "title": "タイトル1"
  }
}
```

### 検索

```
# 検索
GET /messages,titles/_search
{
  "query":{
    "bool":{
      "should": [
        { "wildcard": { "properties.title": "*トル" } },
        { "wildcard": { "properties.content": "*トル" } }
      ]
    }
  }
}

# => 結果のJSONデータ messagesインデックス、titleインデックスからデータを検索できている
{
  "hits" : {
    // ...
    "hits" : [
      {
        "_index" : "messages",
        "_type" : "_doc",
        "_id" : "VfjKv3EBFmjJ_Mf0kBdQ",
        "_score" : 1.0,
        "_source" : {
          "properties" : {
            "channel_id" : 4,
            "content" : "トルトル"
          }
        }
      },
      {
        "_index" : "titles",
        "_type" : "_doc",
        "_id" : "VvjKv3EBFmjJ_Mf0rBch",
        "_score" : 1.0,
        "_source" : {
          "properties" : {
            "channel_id" : 1,
            "title" : "タイトル1"
          }
        }
      }
    ]
  }
}

```

## その他：エイリアスを設定する

今回のケースのように複数のインデックスからの検索を行うケースの場合は事前にエイリアスを設定しておくこと。

なぜなら、検索対象インデックスの増えたとき

* エイリアスを設定していないと、変更範囲がElasticsearchのレイヤーだけではなくてアプリケーションレイヤーにまで影響が出てしまうため。
* エイリアスを設定していれば、Elasticsearch側にてインデックスをエイリアスに新しく追加するだけの閉じた影響範囲になる。

実際にエイリアスの設定と検索をしてみる。

```
# エイリアス設定: searchableエイリアスを作成する
POST /_aliases/
{
  "actions": [
    { "add": { "indices": [ "messages", "titles"],  "alias": "searchable" } }
  ]
}

# 検索: インデックスと同じようにsearchableエイリアスを対象に検索する
GET /searchable/_search
{
  "query":{
    "bool":{
      "should": [
        { "wildcard": { "properties.title": "*トル" } },
        { "wildcard": { "properties.content": "*トル" } }
      ]
    }
  }
}

=> 結果はインデックスもエイリアスも変わらない
{
  "hits" : {
    // ...
    "hits" : [
      {
        "_index" : "messages",
        "_type" : "_doc",
        "_id" : "VfjKv3EBFmjJ_Mf0kBdQ",
        "_score" : 1.0,
        "_source" : {
          "properties" : {
            "channel_id" : 4,
            "content" : "トルトル"
          }
        }
      },
      {
        "_index" : "titles",
        "_type" : "_doc",
        "_id" : "VvjKv3EBFmjJ_Mf0rBch",
        "_score" : 1.0,
        "_source" : {
          "properties" : {
            "channel_id" : 1,
            "title" : "タイトル1"
          }
        }
      }
    ]
  }
}
```

## REF

* [Elasticsearch インデックス・エイリアス - Hello! Elasticsearch. - Medium](https://medium.com/hello-elasticsearch/elasticsearch-c8c9c711f40)
【Swift】R.Swiftの導入(CocoaPods)

## 環境
Swift: 5.2.2
Xcode: 11.4.1
CocoaPods: 1.9.0

## 導入方法
[R.Swift](https://github.com/mac-cain13/R.swift)でCocoaPodsを推奨しているので、それで導入していきます。

##1.
Podfileに以下を追加したのち、`pod install` を行ってください。

```:Podfile
 pod 'R.swift'
```

##2.
Xcode上のファイルリストでプロジェクトをクリックしてください。次に、`TARGETS`を選択して、中央部のタブにある、`Build Phases`をクリックしてください。そして、中央部の左側にある小さいプラスボタンを押して、`New Run Script Phase`を追加してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256549/5aeab961-e532-55a3-ddc5-0a2feede3fd3.png "手順１")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256549/5fe1a3a9-19de-33e2-05f8-7a4a39f72542.png "追加するもの")

##3.
`Run Script`を展開してください。画像を参考にしながら適切な場所に適切なコードを記入してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256549/d333894c-a23c-c57c-1f58-ec508a3b5ca2.png)

(3.1)　一番上のところ

```
"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/$PROJECT_NAME/R.generated.swift"
```

(3.2)Input Filesの「＋」をクリックして以下を追加してください。

```:InputFiles
$TEMP_DIR/rswift-lastrun
```

(3.3)Output Filesの「＋」をクリックして以下を追加してください。

```:OutputFiles
$SRCROOT/$PROJECT_NAME/R.generated.swift
```

##4.
「⌘ + B」でビルドしてください。そうすると、プロジェクトのルートフォルダに`R.generated.swift`が生成されていると思うので、それをxcodeにドラッグ&ドロップしすると最終的に以下の画像のようになります。その際に、`copy items if needed`のチェックボックスをオフにするようにしてください。
これで導入は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256549/1551e3b0-4a4e-3c98-f008-43fd394ac103.png)

## 終わりに
大規模な開発において、エラーの原因、タイポをなくせるためかなり便利だと感じました。
R.Swiftだけでなく初学者が学ぶような技術を用いたタスク管理アプリを作ったので、併せてご確認いただけると幸いです。

タスク管理アプリ: https://github.com/taitai9847/TusTasks

## 参考
参考にさせていただきました。ありがとうございます。

- https://qiita.com/uhooi/items/82fbdd94bdc467a22422
- https://github.com/mac-cain13/R.swift
【Date.today】 今日だけの情報を取り出す方法　rails

![スクリーンショット 2020-04-28 17.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620689/ea799895-ba94-d486-4035-f184501be932.png)

#【ゴール】
本日の注文履歴の情報を取り出す

#【開発環境】
■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7

#【実装】
今日のみの情報　
　　↓
今日の情報全て　
　　↓
created_atカラムを対象に、whereメソッドを使用し抽出


```対象.controller
　@order = Order.where("created_at >= ?", Date.today)
```

※今回は「本日の注文履歴」を表示
※"where"メソッドで該当するもの全てを取得
※"date.today" で本日の日付を取得


以上
[Rails]ポリモーフィックな中間テーブルにthrough関連を定義する

railsでポリモーフィック関連のある中間テーブルにthroughを定義する方法を調べたので忘備録です。便利だけどあまり、情報が落ちてないです。

# 説明すること/しないこと
* 説明すること
  RailsのActiveRecordにおいて、ポリモーフィック関連が定義されてる中間テーブルがある場合のthroughの定義方法。

* 説明しないこと
  ポリモーフィック関連やthrough関連の詳細な説明。

# 通常のthrough関連付け
以下のような関連が各モデルにあるとします。
![スクリーンショット 2020-04-27 20.47.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388573/6b148879-a8a8-edb6-3112-0a8e3cbcc913.png)

companyは複数のeventを主催することができ、また、複数のcompanyが共同でeventを主催できます。この場合、以下のような関連付けを定義します。

```model.rb
class Company < ApplicationRecord
  has_many :event_owners
  has_many :events, through: :event_owners
end
 
class EventOwners < ApplicationRecord
  belongs_to :company
  belongs_to :event
end
 
class Event < ApplicationRecord
  has_many :event_owners
  has_many :companies, through: :event_owners
end
```

するとEventOwnerを介してevetに紐づく複数のcompanyを以下のように取得することができます。

```console
> event.companies
=> # [company1, company2]
```
さて、ここまでは知っての通りです。

# ポリモーフィック関連でのthrough関連
それではここで、comapnyの他に一般のuserもイベントを開催できるようになった場合を考えてみます。関連図は以下のようになります。
![スクリーンショット 2020-04-27 20.53.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388573/511b13f1-55d9-567a-df53-7572e69f6490.png)

ではさっそく、ポリモーフィック関連を定義してみましょう。

```model.rb
class Company < ApplicationRecord
  has_many :event_owners, as: :eventable
  has_many :events, through: :event_owners
end

class User < ApplicationRecord
  has_many :event_owners, as: :eventable
  has_many :events, through: :event_owners
end

class EventOwners < ApplicationRecord
  belongs_to :event
  belongs_to :eventable, polymorphic: true # ポリモーフィック関連
end
 
class Event < ApplicationRecord
  has_many :event_owners
 # 以下がポリモーフィックなthrough関連
  has_many :companies, through: :event_owners, source: :eventable, source_type: 'Company'
  has_many :users, through: :event_owners, source: :eventable, source_type: 'User'
end
```

through関連でsourceを定義することで、以下のようにeventに関連するuser or companyを取得することができます。

```console
> event.companies # or event.users
=> # [company1, company2]
```
ちょっと前まで知らなかったけどめっちゃ便利やん！
上部にfixedで固定したいとき

ページの途中にある要素をそこまでスクロールしたらページ上部に張り付かせる。
そんな実装を求められることが時たまあります。

今までfooter側に固定はそこそこありましたがheader側に固定はあまりなかったので苦戦。
備忘録かねて記録しておきます。

もともと、ページに存在していた要素をfixedで固定しようとJavascriptからいじってましたが、こうするとfixedした瞬間に元の要素分の高さがなくなってガクっとおかしな動きをします。

そこで、固定したい要素と全く同じものを用意して、元の要素は何もいじらずに代用のものをfixedしたりnoneしたりすることでこの問題を解決します。


scrollPositionは現在のスクロール位置、fixedPositionは要素を固定したい基準のスクロール位置です。

```javascript
    if (scrollPosition <= fixedPosition) {
        $('#substitute-float-top-content').css({
            display: "none",
            position: "static",
        })
    } else {
        $('#substitute-float-top-content').css({
            display: "block",
            position: "fixed",
            top: 0
        })
    }
```
つまりdockerってなんで必要なの？噛み砕いてみた

## 近況報告
　まだ手直しする場所は多々ありますがとりあえず個人アプリをデプロイ，readme作成は完了しました。今後の方針としましては，，，

・個人アプリの修正及び機能付与
・カリキュラムのドリル
・新しいことへのチャレンジ（dockerとGo言語）
・就職活動

として頑張って行きます。

# 今回のゴール
・dockerを勉強する意味がよく分かんないひとにわかりやすく言語化
・正確なdockerの知識は書籍や一次ソースをみてね
・大枠の理解を目的にしてるので以下の内容は必ずしも正しいわけではないよ

dockerを勉強始めたのですが，出てくるカタカナや空間認識がさっぱりだったので，そもそもなんのためにdockerが利用されているのかをさらってみたらなんとなく構造が見えてきたので，備忘録として残します。

## お題１
Dockerてなんで注目されてるの？

## 結論
ユーザーの声に対し**迅速に**応えるために適した手段だからだよ。

## どういうこと
サービスを改良していく際にメインとなるのは，ユーザーからの要望に応えていく，ということになると思います。ただ，それを行なっていくには，
要望　▶️　開発チームが改良　▶️　本番環境の運用チームが反映
というプロセスを踏んでいくと思われます。

テックキャンプを受講したかたはわかるかもしれませんが，開発環境で作成したアプリケーションはそのまま本番環境で動かすことができたでしょうか。テスト環境はできたでしょうか。それぞれ環境を設定し直さなければいけない場所があったと思います。

これは上記のプロセスにも言えて，本番環境のチームはうまく運用できているところに新しい技術を取り入れるために環境整備した結果，エラーが発生したり，サーバーが重くなることを嫌がります。そりゃクレームにつながるし，自分らの仕事に支障が出るし嫌ですよね。ただ，開発チームはユーザーに応えるために改良しているので悪気はないです。じゃあこのちぐはぐをどうすれば解決できるのか。そうです，**全ての環境を一緒にしちゃえばいいのです**。

これを実現できるのがコンテナ運用，つまりdockerの意義というわけですな。

そうすれば開発チームの行なったことはすぐに本番環境に反映することができます。そして運営チームはスムーズに運営ができ，結果としてユーザーの要望にスピーディに応えることができるようになります。

ちなみに，開発チーム（Development）と運用チーム（Operations）がお互いに協調し合うことで、開発・運用するソフトウェアやシステムの価値をより高めるだけでなく、そのビジネスの価値をより確実かつ迅速にエンドユーザーに届け続ける仕組みを**DevOps**といいます。[参考](https://www.buildinsider.net/enterprise/devops/01)


## お題２　
dockerは従来の運用となにが違うの？

## 答え（大枠の理解が目的なので正解の自信はありません）
[dockerについて](https://cn.teldevice.co.jp/column/10509/)
従来の仮想化　1つのOSに複数の仮想OSを置いて，各OSがアプリケーションを動かす
docker　　　　1つのOSに１つの仮想OSを置いた土台を置いてその上にコンテナを置く

コンテナの中にアプリケーションがはいっていると考えてください。各コンテナは土台と互換性があるので付け替えても不具合が起こりにくいです。OSを複数使わない分プロセッサやメモリの消費は少なく、ストレージの使用も減る。そのため、仮想マシンに比べて起動時間が短く、同じ性能のハードウェアであれば、より多くのコンテナを同時に動かすことができます。
 
ただ，コンテナ起動の元となる部分はみんな統一されるため，アプリケーションごとにOSを変更したりできないと柔軟性は欠けますが，１つのサービスを回すという点ではそこまで悪い欠点ではないのかな。


##終わりに
不備はたくさんあると思いますが，docker勉強始めて1日目なので温かい目でみてください。。。他にもいいこと悪いことあると思いますが，そこは勉強していくうちに理解していければと。

微量でも参考になったらLGTM，ご指導はコメント欄にお願いします！
GitHubの使いかた

#はじめに
こちらではGitHubの簡単な使いかたをご紹介します
使い始めたばかり向けになるのでGUIでの紹介になります。
（今現在画像アップロードに制限がかかっているので画面ベースの紹介はご容赦ください。。。）

#なににつかうの？
・コードの共有/レビュー
・展開して他のユーザに共有
・備忘録など



#使い方
ログインされていることを前提とさせていただきます。

1.右上のユーザアイコンか「Your repositories」

2.画面内の「New」を押下

3.名前と公開するか否か選択して「Create repository」

4.「uploading an existing file.」を押下

5.画面にアップロードしたいものをD&D

６.「Commit chenges」を押下

つぎからは「UplodeFiles」を押下しファイルをアップロード
できます。
差分はHistoryがあるのでそこから更新履歴がみれます。

#まとめ
いかがだったでしょうかいずれ画面ベースの紹介に書き換えていきたいですね。
[Go言語] ContextのWithValueのkeyについて

## ContextのWithValueでのワーニング
ContextのWithValueで以下のようにstringを使おうとすると、```should not use basic type string as key in context.WithValue```のwarningが出てしまいます。

```go
ctx = context.WithValue(ctx, "user", user)
```

調べてみたところ、WithValueを使っている場所で好き勝手にkeyを設定すると、key名が被ってしまう可能性があるのというエラーのようでした。とても親切ですね。

## 解決策
utilを作成して、そこでWithValueの処理を一括して行うように修正をしました。
ポイントは以下の4点になります

1. typeで```valueKey```を宣言する
2. constで必要な```valueKey```を宣言する
3. ```WithValue```の関数の引数を```valueKey```にする

```go
package ctxutil

import "context"

const (
	// ポイント②
	LayoutKey valueKey = iota
	UserKey
)

// ポイント①
type valueKey int

// ポイント③
func WithValue(parent context.Context, key valueKey, v interface{}) context.Context {
	return context.WithValue(parent, key, v)
}
```

### 呼び出し
呼び出しは以下のように書けます。

```go
ctx = ctxutil.WithValue(ctx, ctxutil.UserKey, user)
```

以上です！
SPRESENSEに書き込みができないとき

# 問題
- Spresense SDKを利用した開発
- `flash_writer`が起動するだけで書き込みが行われない
    - Arduinoでも同様
    - ホストのプラットフォームを変えても同様
- UART経由でNuttShellにログインすることはできる（＝致命的な故障ではない）

# 原因
残念ながら現時点では不明。
何らかがトリガになって書き込み保護が有効に？

# 解決
[Spresense recovery tool](https://developer.sony.com/ja/develop/spresense/developer-tools/spresense-recovery-tool) を使って工場出荷時の状態にリセットする。日本語ドキュメントは付属しているが、Spresense SDKのドキュメントにはあまりこのツールの記載がないため見落とす場合が多いように思われる。
Windows10: pythonのdlibライブラリのインストール

普通にインストールするとビルドエラーがでます。

前提
Anaconda3をインストール済み

[cmakeのインストール](https://cmake.org/download/)
installer版でOSに合ったものをダウンロードしてインストール。
例: cmake-3.**.*-win64-x64.msi

install Optionsでは、
Add CMake to the system PATH for all usersを選ぶ。

Anaconda Promptから、
$ pip install dlib

インストール＆ビルドできるはずです。
Pentaho Data Integrationに3rdパーティーツールのドライバーを組み込みSalesforceに接続

##検証概要
オープンソースETLのPentaho Data Intagration(PDI)に3rdパーティーツールDataDirect JDBC for Salesforceのドライバーを組み込みSalesforceに接続してデータを取得します。
##検証環境
- Java Versin 8 Update 351(https://java.com/ja/download/)
- Pentaho Data Integration 9.0(http://community.pentaho.com/)

##PDIにDataDirect JDBC for Salesforceを組み込む
1. https://www.progress.com/jdbc/salesforce よりDataDirect JDBC for Salesforceをダウンロード・インストールをします。

1. PDIにドライバーをインストールします。
"C:\Program Files\Progress\DataDirect\JDBC_60\lib\sforce.jar"のドライバーをコピーして、
"C:\Pentaho\design-tools\data-integration\lib”配下に配置してください。
PDIを起動している場合は再起動が必要です。

1. PDIを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/a45d5fcf-e27b-90d1-a3dc-6b587041f35e.png)

1. 「データ変換」をダブルクリックするとファイルが新規作成されます。ビュータブに戻り「データベース接続」をダブルクリックしてデータベース接続設定を行います。

1. 以下を設定してください。
接続タイプ「Generic Database」
アクセス「Native(JDBC)」
カスタム接続URL「jdbc:datadirect:sforce://login.salesforce.com」
カスタムドライバークラス名「com.ddtek.jdbc.sforce.SForceDriver」
ユーザ名「Salesforceのユーザ名」
パスワード「Salesforceのパスワード＋セキュリティトークン」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/8a09f1d6-2a09-a9cc-1d20-c5c112e3bc36.png)
「テスト」で接続の確認を行っておいてください。

##テーブルを取得して、Excelに出力
1. デザインタブ→「入力」→「テーブル入力」をダブルクリック  
1. 入力するテーブルはステップの設定から行います。
データソースを指定して「SQLの選択」をクリック。「テーブル」から入力するテーブルを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/1fa3e646-46b6-fe8a-02ff-9b3d787099dd.png)

1. デザインタブ→「出力」→「Excel出力」をダブルクリック
1. ステップをShiftを押しながらドラッグして結合します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/eb7158ad-78da-aef9-575f-1a1c4ecfadc8.png)
1. ファイルを保存後、実行してExcelに出力します。
【JavaScript】mapでオブジェクトの配列の中身を確認する 

##やりたいこと
オブジェクトの配列`objectArray`の中に、`color = 'blue'`なオブジェクトが存在するかを（シュッとした感じで）判定したい。 

```JavaScript
const objectArray= [{color: 'red', type: 'soft'}, 
                    {color: 'blue', type: 'hard'},
                    {color: 'pink', type: 'soft'}, 
                    {color: 'black', type: 'hard'}]
```

文字列の配列なら`includes`で判定できますが、オブジェクトの配列だとうまくいきません。

```JavaScript
const stringArray = ['blue', 'red', 'pink', 'pink']

console.log(stringArray.includes('blue'))
// expected output: true

console.log(objectArray.includes('blue'))
// false になってしまう
```

##どうする
はじめに`map`を使って文字列の配列にし、そのあとで`includes`で判定します。

```JavaScript
console.log(objectArray.map(x => x.color).includes('blue'))
// expected output: true
```

これで判定ができました。~~（シュッとしてるね！）~~
※@sdkei さんにコメントいただいた書き方のほうが良いので追記しました。→ [追記その２](#2020-04-28-追記その２)

##おまけ
blueは何番目にあるのか？を知りたい場合もある（というか、こっちのほうが多い？？）と思いますので、２つ紹介します。(２つ目はmap使ってないけど)

```JavaScript
console.log(objectArray.map(x => x.color).indexOf('blue'))
// expected output: 1

console.log(objectArray.findIndex(({color}) => color == 'blue'))
// expected output: 1
```
colorに重複がある場合は一番小さいindexだけが出てくると思います。blueなオブジェクトのindexをすべて取得したい場合はこんな感じでしょうか。（シュッとしてませんが勘弁してください）

```JavaScript
const objectArray2= [{color: 'red', type: 'soft'},
                     {color: 'blue', type: 'hard'},
                     {color: 'blue', type: 'soft'},
                     {color: 'pink', type: 'soft'},
                     {color: 'black', type: 'hard'}]

const result = objectArray2.map((val, itr) => val.color == 'blue' ? itr : -1).filter((x) => x != -1)
console.log(result)
// expected output: Array [1, 2]
```
※@norkron さんにコメントいただいた書き方がシュッとしているので追記しました。→ [追記その１](#2020-04-28-追記その１)
※@ttatsf さんにコメントいただいた書き方もシュッとしているので追記しました。→ [追記その３](#2020-04-29-追記その３)

以上、ご清聴ありがとうございました。
(どちらも`map`を使わないほうが良いケースだったため、不適切なタイトルになっていますね。ゴメンナサイ。）

#2020-04-28 追記その１
@norkron さんからコメントをいただきました。
`filter`を使わない、シュッとした書き方になっています。

```JavaScript
const objectArray2= [{color: 'red', type: 'soft'}, 
                     {color: 'blue', type: 'hard'},
                     {color: 'blue', type: 'soft'},
                     {color: 'pink', type: 'soft'}, 
                     {color: 'black', type: 'hard'}]

const result = objectArray2.flatMap((val, itr) => val.color == 'blue' ? [itr] : [])
console.log(result)
// expected output: Array [1, 2]
```

#2020-04-28 追記その２
@sdkeiさんからコメントをいただきました。
`some`を使った、より良い書き方です。（見た目も計算効率も良いです。）

```JavaScript
console.log(objectArray.some(x => x.color === 'blue'));
```

#2020-04-29 追記その３
@ttatsfさんからコメントをいただきました。
三項演算子とスプレッド構文を使ったシュッとした書き方です。

```JavaScript
objectArray2.reduce((acc, obj, i)=> obj.color==='blue' ? [...acc, i] : acc, [] )
```
<初心者>Laravelアプリの新規作成とMySQLとの連携

#目的
Laravelアプリを新規作成する時にやり方をよく忘れるのでメモしました。

##環境
MacOS Catalina
インストール：Laravel 5.7 / composer / mysql 5.7 / Sequel Pro / git / github desktop / github登録

##プロジェクトの新規作成
プロジェクト名、バージョンを指定しつつ、作りたいフォルダに移動した後に下記コマンドを実行します。
サーバーを起動してサイトが表示されるかを確認します。

```
# 新規作成
$ composer create-project laravel/laravel プロジェクト名 --prefer-dist "5.7.*"

# バージョン確認
$ php artisan -v

# サーバー起動
$ php artisan serve
```

##MySQLへの接続
下記を行うには、予めmysqlでパスワードの設定等をしておく必要があります。

```
# MySQLへログイン
$ mysql -u root -p;

# データベース一覧を確認
mysql$ SHOW DATABASES;

# データベースを作成
mysql$ CREATE DATABASE `データベース名`;
mysql$ USE データベース名;
mysql$ SHOW TABLES;
mysql$ exit
```

## GitHubで管理

```
# 作成したプロジェクトのディレクトリで下記を実行。gitを初期化
git init
```
上記を実行後、GitHub Desktopアプリで"Add Existing Repository"から追加してmasterへpush

##プロジェクトの設定ファイルを編集
.envファイルの下記箇所を編集

```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=データベース名 #変更
DB_USERNAME=root #変更
DB_PASSWORD=secret #変更
```

上記を変更したあとは、キャッシュをクリアする

```
php artisan config:cache
```

##マイグレーションを実行

```
php artisan migrate
```

下記エラーが出ることがあります。emailのバリデーションを指定しないといけないみたいです。

```
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `password_resets` add index `password_resets_email_index`(`email`))
```

一旦、作成したテーブルをsequel proで削除し、下記のようにマイグレーションファイルを変更し、再度マイグレーションを実行すればOKです。

変更するファイル
- password_resets_table.php
- users_table.php

```
# before
table->string('email')->index();

# after
table->string('email', 50)->index();
```


ここまでで、アプリの新規作成とデータベースを使う準備が完了しました。お疲れ様でした！
AWSのVirtual MFA Deviceを失ったときどうなるかとその予防

#最初にざっくりいうと
「MFA デバイスの割り当て」（Virtual Multi-factor Authentication device）にスマホを使うなら、
機種変するときに気をつけましょうね。デバイスなくなるとホントに入れないからね。
という話。その後の大変だったお話と、その後ワタシが見つけた他に乗ってない（はずの）予防法についても記載します。
参考になったらLGTMしてね！（「いいね！」じゃなくていいにくい…）

#ことのはじめ
AWS好きなので日々いろんなサービスをありがたーく使わせております。
で、2016年ごろから「rootで作業するな、認証は２段階にしろ」というお達しがあったので、素直にポリシ、グループ、ユーザを細かく作った上で、root他多数のユーザはスマホをデバイスとしたMFA(Multi-Factor Authentication)で２段階認証するようにしました。

時を経て、すっかりrootのMFAのことを忘れていたワタシはある時
:angry:今のスマホは大きすぎる！
と思ってスマホを[unihertz Atom](https://www.unihertz.com/ja_JP/shop/product/atom-2)に変えたわけですよ。

さらに時を経て、2020年3月末。[COVIT-19](https://www.covid19-yamanaka.com/cont1/main.html)の状況から
そうだ、Amazon Workspaceを使おう！でも、権限付与してないから久々にrootで入らないとなぁ
と思って入ろうとした時に気が付きました。

:cold_sweat:**認証のアレないやん！**

…ここから長い旅の始まりとなりました。

#そんなときのための「別認証」も失敗
GoogleのもMFA使ってますが、あちらは他のデバイスで認証とかもできるので、他のデバイスで認証後改めて「認証のアレ」を取得できたのですが…
AWSはそういうのがない。

まぁでも別の認証方法でやればいいさ

というわけで、次の方法はSMSでワンタイムパスワードを発行後、さらに登録している電話番号で認証するというやり方。
そういうふうにWebにもあります。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html

で、そのとおりやろうとしたら…なんかうまくいかない！

何回かやったけど、SMSはくるのに、その後の手順による「電話」が来ない！

:cold_sweat:おかしいでしょ！SMSと同じ番号よ！

とは言え、もうどうしようもなく、しばらく問題を放置することにしました。[^1]

#サポートセンターにお問い合わせ
さらに時が流れ4月下旬:mask:。あっという間にテレワークが進みましたが、我が職場は輪番休暇というなんともIT業界とは思えない対応となり、ともあれ自宅にいる時間が増えたのでAWSのMFAの件を解決させておくか！と思い立って問合せすることにした。

認証失敗した画面にあるリンク（画をとっておけばよかった…）から進むと
サポートセンターへの問い合わせする内容を入力させる画面になり
ID（直前の画面にもあるし、SMS送信したメールにも、毎月の明細にもある）などを入れさせて
サポート言語（日本語！）
を入れて、待つことにした。

すると、翌日朝9:00過ぎに札幌から見知らぬ電話。
あやしいなぁ（←前日問い合わせしたのを忘れている）
とか思いながら電話にでると

:woman_tone1:「AWSカスタマーセンターですぅ」

という声。あーお願いします。

途中、本人確認がありましたが、ここではざっくりと。
ユーザ情報に登録していた電話がつながったので割と簡単だったかな。
[こちらの方](https://qiita.com/K-1/items/a8b88cc4b13d99bb5002)は引っ越しもしたためか「MFA解除に必要な書類」までとったらしいですが、ワタシはそこまで求められませんでした。

:woman_tone1:「お客様のアカウントですね、MFAの設定がすでに解除されているようです。お手数ですが、いま改めて操作いただけませんか？」

へぇ？でもまぁ操作するけど、やっぱりダメ。

:cold_sweat:「今もMFA入力を求められます。」
:woman_tone1:「そうですか、すみません。改めてこちらでお調べして見ます」
…（１分ほど）
:woman_tone1:「こちらの不具合かもしれません。ここでは一旦rootのMFAを削除します。パスワードだけでログオンできる状態になりますので、改めてMFAの設定をおすすめします」

おお、なんと素早い。ありがとう。 [^2] 

こんな流れで改めてrootでログオンできましたとさ。
rootで入れれば、他のユーザのMFAは自分で削除できるからね。

#予防しなきゃ

とはいえ、普段使わないアカウントのことを忘れないようにするのはしんどいですなぁ…と考え、対策はないものかと調べると
https://forums.aws.amazon.com/thread.jspa?messageID=315984
この投稿にたどり着きました。
お互いに奥歯にものが挟まった言い方をしているようですが…そりゃま仕方ないわな。

```
表示されるQRコードをバックアップしとけばいいじゃないか
```

ということですね。まぁでもちょっと抵抗がありますね。というわけで、ワタシは以下の対応で。

```
あらかじめ複数の端末にAuthenticatorをインストールしておき
MFR登録のQRコード表示時にそれら複数の端末で認証キーを取り込む
```

これならバックアップしたQRコードの保管に悩まないし、複数の端末にあれば
「やっちまった！:scream_cat:」
という今回のワタシのようなことはなくなるかと思います。

これでダメになるときは…
・忘れすぎて全部の端末からMFA消す
・（あまり考えたくないですが）天災などで全端末が一気に使えなくなる
ぐらいでしょうか。

#最後に
AWSの日本語サポートって案外親切でした。もっと冷たい対応されるのかなぁと思ってたので。
ありがとう。

[^1]: 権限の少ないユーザは利便性のためにMFA使ってなかったので、最低限の作業はできていた。
[^2]: 後からアカウント情報を見ても電話番号登録に誤りはなかった。そりゃそうだわなSMSは来るんだから…結局なんで失敗してたのかはわからなかった。
【Ruby】f.collection_select　を使ってみた

フォームを作っている中で選択肢を持たせた見え方にしたく調べたので、残しておきます。

#　f.collection_selectとは
よく見るこういうセレクトボックスが作れます！
https://gyazo.com/376813aa3d81a93cf8ba338e0e2285f2
##　ドキュメントを読む

初めて使うのでまずはrailsドキュメントを読んでみました。
https://railsdoc.com/page/collection_select

### 説明
選択ボックスをモデルの情報を元に生成

### 使い方
    collection_select(オブジェクト名, メソッド名, 要素の配列, value属性の項目, テキストの項目 [, オプション or HTML属性 or イベント属性])

```f.object
f.collection_select(メソッド名, オブジェクトの配列, value属性の項目, テキストの項目 [, オプション or HTML属性 or イベント属性])
```
？？どういうこと

つまりモデルから引っ張ってきた選択肢から選んでDBに送ろうよということ

##具体例

```ruby.rb
f.collection_select(:name, @categories, :id, :name)
```

↓上記の結果

```
<select id="page_name" name="page[name]"><option value="1">Railsの基礎知識</option>
<option value="2">Rubyの基礎知識</option>
</select>
```

#### 第一引数
メソッド名　:name
この情報をもとに、selectタグのid属性、name属性を決める。
↓の〇〇部分が決まる

    <select name="○○" id="◯◯">

#### 第二引数
オブジェクトの配列 @categories
その選択肢はどの配列がもとになるの？ということ
前提としては
```
@categories = Post.all
```
のように定義されているモデルから配列を取り出してある状態

#### 第三引数
:id value属性の項目
ここにvalueが入る、つまり選択された場合ここの値がDBに送られる。今回は:idなのでidが送られる。
↓の◯◯に入る
```
<option value="◯◯">選択肢</option>
```
#### 第四引数
:name
選択肢に実際に表示するのはこれということを指定している。項目は、optionタグ内のテキストに設定したい値のカラム名が入る。nameカラムを選択肢として表示したいので:nameと設定する。
↓の選択肢に:nameが入る
```
<option value="1">選択肢</option>
```

#### 第五引数
これはオプションですが
prompt: "選択してください"
で初期設定でこれが表示されるようになります（オススメ）

##補足
選択肢を別のモデルから引っ張ってきたい場合

```ruby.rb
f.collection_select(:name, @categories, :id, :name)
```
ここの@categoriesを　モデル名.all　とかにしてあげるとそこから選択肢を引っ張ってこれる
モデル名はクラスメソッドなのでどこからでも呼び出せる

具体例（自分が作ったコードの場合）

```ruby.rb
f.collection_select :name, MenuSelect.all, :menu_name, :menu_name, prompt: "何をしましたか？", class: 'form-control'
```
##クラスが付けられない
**※クラス名の付け方**

```.rb
= f.collection_select :postage_player_id, PostagePlayer.all, :id, :name,{prompt: "選択してください"}, {class: "new-wrapper__main__input-select"}
```
,{prompt: "選択してください"}, {class: "new-wrapper__main__input-select"}こんな感じでpromptとclassを引数として渡してあげるとクラスが設定できます。

参考文献

https://railsdoc.com/page/collection_select

https://minimalist-10.com/study/rails-collection_select/

https://qiita.com/yokke0059/items/9508150c47b8a130e3df
Flutter マテリアルデザインのテキストテーマ一覧

Text ウィジェットを扱っていて `style: Theme.of(context).textTheme.XXXXXX` のかたちでテキストスタイル（フォントサイズ、フォントの太さ、文字間隔）を指定することは多々あります。

**どれだけ種類があって、デバイス上でどのように表示されるか** 調べてみましたが、パッと見でわかりやすいものがなかったのでまとめました。



## 公式ページより

[こちら](https://api.flutter.dev/flutter/material/TextTheme-class.html) のページでテキストテーマについて取り上げられています。

| NAME     | SIZE  | WEIGHT | SPACING |
| -------- | ----- | ------ | ------- |
| display4 | 112.0 | thin   | 0.0     |
| display3 | 56.0  | normal | 0.0     |
| display2 | 45.0  | normal | 0.0     |
| display1 | 34.0  | normal | 0.0     |
| headline | 24.0  | normal | 0.0     |
| title    | 20.0  | medium | 0.0     |
| subhead  | 16.0  | normal | 0.0     |
| body2    | 14.0  | medium | 0.0     |
| body1    | 14.0  | normal | 0.0     |
| caption    | 12.0  | normal | 0.0     |
| button    | 14.0  | medium | 0.0     |
| subtitle    | 14.0  | medium | 0.0     |
| overline    | 10.0  | normal | 0.0     |

![公式.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135956/239a24d4-9522-c639-baa9-24d5bf064918.png)


このように一覧化はされていてテーマごとの文字も表示されているのですが、実際にデバイスで表示させたときのイメージが湧きませんでした。
（そしてなぜか `subtitle` と `overline` のテーマは載っていない）



## デバイスに表示させてみる

![textTheme.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135956/663b5e0a-8f85-ea4b-5bd2-d54fc1bcd2ed.png)


端末に表示させるとこんな感じになるようです。

一応、テーマを利用しているところのソースコードも載せておきます。

```dart

// 省略

body: Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Text(
        'display4',
        style: Theme.of(context).textTheme.display4,
      ),
      Text(
        'display3',
        style: Theme.of(context).textTheme.display3,
      ),
      Text(
        'display2',
        style: Theme.of(context).textTheme.display2,
      ),
      Text(
        'display1',
        style: Theme.of(context).textTheme.display1,
      ),
      Text(
        'headline',
        style: Theme.of(context).textTheme.headline,
      ),
      Text(
        'title',
        style: Theme.of(context).textTheme.title,
      ),
      Text(
        'subhead',
        style: Theme.of(context).textTheme.subhead,
      ),
      Text(
        'body2',
        style: Theme.of(context).textTheme.body2,
      ),
      Text(
        'body1',
        style: Theme.of(context).textTheme.body1,
      ),
      Text(
        'caption',
        style: Theme.of(context).textTheme.caption,
      ),
      Text(
        'button',
        style: Theme.of(context).textTheme.button,
      ),
      Text(
        'subtitle',
        style: Theme.of(context).textTheme.subtitle,
      ),
      Text(
        'overline',
        style: Theme.of(context).textTheme.overline,
      ),
    ],
  ),
),

// 省略

```



## おわりに

技術的な情報が何もなくてごめんなさい 🙇🙇🙇

ただ、 テキストテーマを使おうとして **あれでもない、これでもない、としている時間がもったいない** と思ったのでまとめました。
（ホットリロードが強いとはいえ、テーマ決めるのに手間取ってたらイラついちゃいますしね）

この一覧が、どなたかの役に立てれば幸いです :yum:
AsyncTaskのジェネリスク型パラメータメモ

# AsyncTaskとは
メインスレッドとは別のスレッドで処理できる非同期処理の手段
型忘れちゃうのでメモします
xmlでの表示はListView、SimpleAdapterで適当に出してます

```kotlin:MainActivity.kt

//~~~~~~~省略~~~~~~~~~~~~
    private inner class ListItemClickListener: AdapterView.OnItemClickListener{
        override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            //タップされたIDを取得
            val item = parent?.getItemAtPosition(position) as Map<String,String>
            val Name = item["name"]
            val Id = item["id"]

            val receiver = Receiver()
            //実行
            receiver.execute(Id) //★第一引数！実行するID
        }
    }

private inner class Receiver(): AsyncTask<String,String,String>() {
        override fun doInBackground(vararg params: String?): String { //★第三引数！doInBackground()の戻り値。この場合はresult
            val id = params[0]
            val urlStr = "http://APIのURL/json/v1?city=${id}"

            //~~~文字列で返す処理（省略）~~~~

            return result
        }

        override fun onPostExecute(result: String?) {
           
            //~~~文字列を解析する処理（省略）~~~

            //情報用文字列をセット
            val tvTelop = findViewById<TextView>(R.id.tvTelop)
            val tvDesc = findViewById<TextView>(R.id.tvDesc)
            tvTelop.text = telop
            tvDesc.text = desc
        }
    }
```

#  AsyncTask<String,String,String>()の型についてメモ
- 一つ目の引数はReceiver()を実行するときのexecute()の引数。この場合はId
val id = params[0]に使われている。

- 二つ目の引数はpublishProgress()実行時に渡された引数
- 三つ目の引数はdoInBackground()の戻り値およびonPostExecute()の引数の型
この場合はreturn result　および　onPostExecute(result: String?)
【忘備録】Javascript の関数定義の4つの方法

# はじめに
今までVue.jsとRuby on rails ばかり触ってきてJavascriptの文法を忘れかけてきたので、railsアプリケーションを作る傍、並行して復習していこうかと思います。
今回はJavascriptの関数定義の方法です。

## (1) function命令

```ruby:javascript.js

function getTriangle(base,height){
  return base * height / 2 ;
};
```

最も基本的な関数の定義。
コードを解析・コンパイルするタイミングで関数を登録している為、呼び出し後に記述してもエラーにならず正常に処理してくれる。

※後述の関数リテラル、functionコンストラクターはコンパイル時に登録はしない。呼び出し時に評価される為、呼び出し元より先に定義する必要がある。

例）

```ruby:javascript.js
console.log(getTriangle(5,2));
// => 5

function getTriangle(base,height){
  return base * height / 2 ;
};
```



## (2) functionコンストラクター経由で定義 

```ruby:javascript.js

var getTriangle = new Function ( 'base','height', 'return base * height / 2' );
};
```
functionコンストラクターを利用して定義する方法。
function命令に比べて、クォートで囲わないといけなかったりする為、余計なコーディングミスをしやすい。
特別な理由がない限り、使うメリットはほぼ無し。
※ functionコンストラクターは引数や関数自体を文字列として定義出来るメリットはあるが、個人的にあまり使いたくないかも。


## (3) 関数リテラル 
```ruby:javascript.js

var getTriangle = function(base,height){
  return base * height / 2 ;
}
```
Javascriptにおいて関数はデータ型の一種であるという特徴を利用して、
名前のない関数`function(base,height){　return base * height / 2 ;}`を変数に格納している。



## (4) アロー関数 
```ruby:javascript.js

let getTriangle = (base,height) => {
  return base * height / 2 ;
}
```
Javascriptにおいて関数はデータ型の一種であるという特徴を利用して、
名前のない関数`function(base,height){　return base * height / 2 ;}`を変数に格納している。


# 最後に
久しぶりにJavascript勉強したら、どんな感じで定義してたっけ？となってしまったのでやはり少しずつでも定期的に勉強しないと無駄になりそうで怖い、、、
後でVueも復習しないと、、、
Railsチュートリアル備忘録 -ログイン/ログアウト編-

```
rails generate controller Sessions new
```
```
session[:user_id]=user.id
```
```app/helpers/sessions_helper.rb
module SessionsHelper
  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
  end

  # 現在ログイン中のユーザーを返す (いる場合)
  def current_user
    if session[:user_id]
      @current_user ||= User.find_by(id: session[:user_id])
    end
  end
end

  # ユーザーがログインしていればtrue、その他ならfalseを返す
  def logged_in?
    !current_user.nil?
  end

  # 現在のユーザーをログアウトする
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end
```
## ログイン
```
SecureRandom.urlsafe_base64
=> "q5lt38hQDc_959PVoo6b7A"
```
```app/models/user.rb
class User < ApplicationRecord
    attr_accessor :remember_token
.
.
.
  # 渡された文字列のハッシュ値を返す
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  # ランダムなトークンを返す
  def User.new_token
    SecureRandom.urlsafe_base64
  end

    # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(remember_token)
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end
end
```
## クッキーの暗号化
```
cookies.permanent.signed[:user_id] = user.id
```
検索

```
User.find_by(id: cookies.signed[:user_id])
```
Raspberry Pi に東京都の新型コロナウイルス感染症対策サイトをインストール

東京都の新型コロナウイルス感染症対策サイトを　Raspberry Pi にインストールする方法です。

必要なソフトのインストール

Node.js

```bash
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt install -y nodejs
```

インストールされたバージョン

```text
$ node --version
v14.4.0
```

yarn

```bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn
```

インストールされたバージョン

```text
$ yarn --version
1.22.4
```

ソースコードのクローン

```bash
git clone https://github.com/tokyo-metropolitan-gov/covid19.git
```

依存関係のインストール

```bash
cd covid19
yarn install
```

実行

```bash
yarn dev
```

http://localhost:3000 にアクセス
![tokyo_apr28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e13ba02e-9ac9-3392-431c-35180803ffac.png)
Kotlin Coroutinesのセットアップ&使い方

## はじめに

TBD

## 「Kotlin Coroutines」とは？

TBD

## 環境

- OS：macOS Mojave 10.14.6
- Kotlin：1.3.72
- Gradle：5.6.4
- Gradle plugin：3.6.2

## セットアップ

### インストール

appフォルダ配下の「build.gradle」に追加するのみです。

```diff:/app/build.gradle
dependencies {
+     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.4'
}
```

## `runBlocking`

TBD

## `suspend` 関数

TBD

## Dispatchers

Kotlinには3つのDispatchersがあります。

|Dispatchers|説明|用途の例|
|:--|:--|:--|
|Dispatchers.Main|Androidのメインスレッドでコルーチンを実行する<br />UIの操作や、処理を素早く実行するためのみに使う|- `suspend` 関数の呼び出し<br />- Android UI フレームワークオペレーションの実行<br />- `LiveData` オブジェクトの更新|
|Dispatchers.IO|メインスレッドの外部でディスクやネットワークI/Oを実行するのに適している|- DB(Room)の使用<br />- ファイルの読み書き<br />- ネットワークオペレーションの実行|
|Dispatchers.Default|メインスレッドの外部でCPU負荷の高い作業を実行するのに適している|- リストのソート<br />- JSONのパース|

### Dispatchers.Main

TBD

### Dispatchers.IO

TBD

### Dispatchers.Default

TBD

## CoroutineScope

TBD

## コルーチンの開始

コルーチンの開始方法は2つあります。

|開始方法|戻り値|説明|
|:--|:--|:--|
|`launch`|×|呼び出し元に結果を返す必要がない処理（いわゆる「fire and forget」）を開始するときに使う|
|`async`|○|`await` と呼ばれる中断関数を使って呼び出し元に結果を返す|

### launch

TBD

### async

TBD

## おわりに

TBD

## 参考リンク

- [Improve app performance with Kotlin coroutines  |  Android Developers](https://developer.android.com/kotlin/coroutines)
- [Kotlin コルーチンでアプリのパフォーマンスを改善する  |  Android デベロッパー  |  Android Developers](https://developer.android.com/kotlin/coroutines?hl=ja)
- [Coroutines on Android (part I): Getting the background](https://medium.com/androiddevelopers/coroutines-on-android-part-i-getting-the-background-3e0e54d20bb)
- [Your first coroutine with Kotlin - Kotlin Programming Language](https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html)
一度、FileReader.readAsArrayBuffer()で読み込んだ状態から画像表示用のDataURLを生成する

## 概要

一度、FileReader.readAsArrayBufferで読み込んだ状態から画像表示用のDataURLを生成する。
`FileReader.readAsArrayBuffer()`で読み込んだバイナリデータをバイナリ文字列に変換してからbase64にエンコードする必要がある。

## 実装

```javascript:JavaScript
/// Base64変換を小分けにする
const APPLY_MAX = 1024;
let encodedStr = "";
for (var i = 0; i < this.reader.result.byteLength; i += APPLY_MAX) {
    encodedStr += String.fromCharCode.apply(null, new Uint8Array(this.reader.result.slice(i, i + APPLY_MAX)));
}
encodedData = window.btoa(encodedStr);
```
※`reader.result`には、`FileReader.readAsArrayBuffer()`で読み込んだバイナリがある前提

```html:HTML側
<img src={`data:image/*;base64,${encodedData}`} />
```
※Reactの実装になっているので適時読み替えること


## NG実装

```javascript:JavaScript
const str = String.fromCharCode.apply(null, new Uint8Array(reader.result));
encodedData = window.btoa(str); // base64へ
```

こちらだと、ファイルサイズ（reader.resultの配列のサイズ）が大きい場合に、applyで再起回数が限界を超えてエラーが出る。

## 参考

* [Maximum call stack size exceeded エラーの解決策【applyの限界】](https://pisuke-code.com/js-soln-of-maximum-call-stack/)
【Rails】初めてのactive_hash


# active_hash
- 使いどき：変更や削除がないデータの実装はテーブルは作成せず、モデルに直接書く active_hashを使う。
- データの取得方法：通常テーブルからのデータ取得と同様に扱える。

参考： https://github.com/zilkey/active_hash
※ 更に単純なものは、enumでもok。

# 実装の手順
gemの導入 → `bundle install`

```ruby:Gemfile
gem 'active_hash'
```
## モデルの作成

```
$ rails g model モデル名
```
`{id: 1, name: 'データ1'}`が１つのレコードのイメージ。

```ruby:モデル
class モデル名 < ActiveHash::Base
  self.data = [
    {id: 1, name: 'データ1'}, 
    {id: 2, name: 'データ2'}, 
          :
  ]
end
```
## activehashを外部キーに設定する
(例) Itemテーブルの外部キーにsizeモデル（activehash）のidを保存したい場合

### テーブルに外部キー用のカラム追加
`rails g migration AddColmunToItems`でマイグレーションファイルを作成し、実行すれば、ok。
※ **activehashは、reference型ではマイグレーションエラーになるので注意！**

```ruby:migrate
class AddColmunToItems < ActiveRecord::Migration[5.0]
  def change
    add_column :items, :size_id, :integer, null: false
  end
end
```

### アソシエーション
- Itemモデルに記載。
- sizeモデルには不要。

```ruby:Item.rb
class Item < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :size
end
```

### active_hashによく使うメソッド
| メソッド | 役割 |  
|:------|-----:|
| モデル名.all | 全データ取得 |
| モデル名.first | 最初のデータ取得 |
| モデル名.last | 最後のデータ取得 |
| モデル名.find(1) | id=1の最初のデータ取得 |
| モデル名.find_by_name("データ2") | name=データ2 の最初のデータ取得 |
|モデル名.where(name: "データ2")|name=データ2 の全データ取得|
|モデル名.count|レコードの数を取得|
※ 詳細は https://github.com/zilkey/active_hash を参照。
AWS（AmazonLinux２）・EC2、Laravel7.x/PHP7.4でのデプロイ

#はじめに
意外に記事少なくて困った点、AmazonLinux２にてちょっと変わってた点、Laravelに関してvimいじったところなんかのまとめです。
初見かつ知識も浅いため、何度も色々弄ったり、削除したり、インスコしたり、EC2作り直したりしたことか。。

#めっちゃ参考にさせて頂いたページ！スペシャルサンクス！
・まず、一番最後見つけた、でも一番参考になった神Qiita記事
[・AmazonLinux2でLaravelの開発環境構](https://qiita.com/h19e/items/02d1301d4fdd8dfa88ac#%E5%BF%85%E8%A6%81%E3%81%AA%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

・AmazonLinux（無印）だけどデプロイの参考になったページ
https://qiita.com/masataka715/items/6e46f1f5e53bdff6cd3d

他色々試しまくった記事
https://qiita.com/2no553/items/952dbb8df9a228195189
https://qiita.com/2no553/items/952dbb8df9a228195189
https://qiita.com/nagahama/items/2fdc820791bee5d564ca
https://qiita.com/snowdog/items/121ad82fcbcd17eac779

皆さんサンクス☆すぐそこサンクスK

##PHP7.4の際
```
$ sudo amazon-linux-extras install php7.4
```
上記Qiitaより、
yumアプデのあとに色々とやる手順ありましたが、これが一番シンプルかつ早い！！

>必要な拡張モジュールをインストールしていきます。必要に応じて各自検討ください。
php-xmlは、Laravelインストール時に、phpunitのインストールに必要になるようなので、事前にインストールしておきましょう。

```
$sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml
```




#AWS


##Apacheどないやねん！

>AmazonLinuxの場合は、2.4系を入れる場合は、 httpd24 でしたが、AmazonLinux2の場合は、httpd で、2.4系になるようです。

```
$ sudo yum install httpd
```
若干旧コマンドとと違ってずっとエラー吐いてたわ。。。ありがとうございます。。。



#Laravel編

##バージョンはしっかり確認を！！自戒の念！！
`PHP -vを　ローカルでなく仮想環境の分と合わせる。`


##migrationできない、、、つらい
・たぶんここ怒られてるので、修正を

```
require __DIR__.'vendor/autoload.php';

__DIR__.こいつがいらないです。。。
※ちな.は、PHPの記述のやつです。
```

###そういえば
偶然発見したのですが、とりあえずTOPページアクセスしたときにLaravelのスローしてくれたエラー使って無理くりエラー解消（APkey作成）できたのは感動した。Laravelすごい。。。


#おわりに
また今後、思い出しながら追記します。（別にまたアプリデプロイする時にどうせつまずくでしょうし。）
改めて参考にさせて頂いた皆様に感謝を。
また修正点などあればぜひ