OmniAICreator/Qiita-1.07M huggingface dataset:
CMSとは？なにがいいの？？

#プログラミング勉強日記
2020年9月17日
なんとなくでしか理解していないCMSについて、この機会にまとめる。

#CMSとは
　CMSはContents Management Systemの頭文字をとったもの。Web制作に必要な知識がなくてもWebサイトやコンテンツを構築・管理・更新することのできるシステムのこと。
　通常のWeb制作ではHTMLやCSSなどの知識や技術が必要となるけど、これらの知識がなくてもWebブラウザ上で直接テキストを入力したり画像をアップロードしたりすることができる。

#メリット

##Webページの更新や追加を専門知識なしでできる
　CMSを導入しているWebサイトでは、CMSのインターフェイス上でデータベースに保存されているテキストデータを編集するだけでWebサイトの更新が可能になる。すでに存在しているテンプレートを使うのであれば、新しいページの追加も簡単で、テンプレートを指定してそのテンプレートに必要なテキストや画像を登録するだけでCMSが自動的にページを生成する。

##Webサイト運用の分業化をできる
　企業のWebサイトでは、ページごとに管理担当部門が異なることがある。専門知識や技術を必要とせずにWebサイトを更新することができるので、社内の広報担当者やWeb担当者自身が簡単に情報を発信することができる。
　なので、<b>制作会社や更新作業を依頼する必要がなくなり、外注コストの削減やより早く情報発信をすることができる。</b>

##マルチデバイス対応が容易に
　Webページに必要な画像やテキストのデータをデータベースに保存しておけば、そのデータを閲覧するデバイスに対応したテンプレートに適応することが可能である。

##インターネット環境とブラウザさえあれば更新できる
　CMSはインターネット上にあるサーバで動くので、パソコン自体にインストールする必要がない。インターネットがつながった環境とWebブラウザさえあれば更新することができる。最近ではスマホで更新できるCMSもある。


#参考文献
[CMSとは？初心者でもわかるCMSの基礎知識とメリット、導入事例](https://www.hitachi-solutions.co.jp/digitalmarketing/sp/column/cms_vol01/)
[今さら聞けない「CMSってなに？」：CMS導入のメリット・デメリットをしっかり理解しよう！](https://www.asobou.co.jp/blog/web/about-cms)
yarn install に失敗する "getaddrinfo EAI_AGAIN registry.yarnpkg.com"

本記事は Docker Toolbox を対象としています。**Docker for Windows は対象外**

# Docker が build できない
webアプリ開発のためテストサーバを docker 上にビルドしようとしたら失敗した。 

```
Step 10/11 : RUN cd app && yarn install
 ---> Running in d36ecd97329b
yarn install v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz: getaddrinfo EAI_AGAIN registry.yarnpkg.com".

``` 
以下が問題のファイル

```Docker:Dcokerfile
FROM node:12.16-slim

ENV APP_DIR=/app
WORKDIR ${APP_DIR}
RUN mkdir -p ${APP_DIR}
COPY . ${APP_DIR}

ENV LANG=C.UTF-8
ENV TZ=Asia/Tokyo
ENV NODE_ENV=development
ENV HOST 0.0.0.0

RUN cd app && yarn install

EXPOSE 3000
```

## 環境

- Windows 10 Home 64bit
- Docker version 19.03.1

Windows 10 Home では Hyper-V が使用できないため **DockerToolbox 経由でインストール**  

- [[公式] Install Docker Toolbox on Windows](https://docs.docker.com/toolbox/toolbox_install_windows/)  
- [[Qiita] Windows環境にDocker Toolboxをインストールする](https://qiita.com/KIYS/items/8ac37f6757a6b7f84569)

## 原因
`registry.yarnpkg.com`　の名前解決ができないのは直ぐに分かる。しかし何故？普通にコマンドラインから `nslookup` できるぞ？と思ったら VirtualBox 側の DNS に問題があるようだ。Linux カーネルを用意するため OS とコンテナの間に挟まっており、意外と問題を見落としやすい。VirtualBox 上で叩くと、

```
dcoker@default:~$ nslookup registry.yarnpkg.com
Server:    10.0.2.3
Address 1: 10.0.2.3
nslookup: can't resolve 'registry.yarnpkg.com'
```

# 解決手法
手っ取り早く DNS サーバに`8.8.8.8`をセカンダリーに追加する。

```
dcoker@default:~$ sudo -i
root@default:~# vi /etc/resolv.conf
```

[DNS設定【resolv.conf 】再起動後の上書きを無効化する](https://soypocket.com/it/linux/post-52/)

```diff:/etc/resolv.conf
  nameserver 10.0.2.3
+ nameserver 8.8.8.8
```

`8.8.8.8` は Google Public DNS のアドレスで、DNSで困った時の頼もしい味方。
キーボード配列の違いでコロン`:`が打てず `vi` 終了できない！そんなJIS配列ユーザのあなたは`'+' (Shift + ';')`を押下しましょう。 

[[Qiita] JISキーボードなのにUS配列の環境で文字を打つ](https://qiita.com/hachisukansw/items/efd4b3c2df7e6a8b3779)

これは応急処置なので、VirtualBox を再起動すると元に戻るなど恒久的な解決にはならないので注意。
siunitx「prefix with no unit」

# ダメな例
```TeX
\si{\decibel\milli}
```
siunitx「あまり単位をつけないのに接頭辞を使うなよ…弱く見えるぞ」

# 良い例
```TeX
\si{\decibel\milli{}}
```


```math
    \rm{dBm}
```
siunitx「単位は`{}`かぁ…じゃあしょうがないね」
#### 単位の意味
1mW基準で電力を測定してdBで表示ときに使うらしい

## 注意点
これずっと通用し続けるかどうかはわからない
【オブジェクト指向豆知識(1)】構造化プログラミングよりもオブジェクト指向言語の方が先に登場している

オブジェクト指向がなぜ必要なのかを説明するとき、「構造化プログラミングの限界からオブジェクト指向が求められたのだ」という説明がされることがあります。

これは事実ではあります。ただ、構造化プログラミングの限界が来てはじめて、ゼロからオブジェクト指向の概念やオブジェクト指向言語が考案されたような感じもする説明です。

実際はそうではなく、オブジェクト指向の概念やオブジェクト指向言語は早くから存在していました。それらが後の時代になってから応用され始めたという流れです。

**年表**

- 1962年 プログラミング言語Simulaが登場。この言語はのちに最初のオブジェクト指向言語と呼ばれる。
- 1969年 エドガー・ダイクストラ、論文「構造化プログラミング」を発表。
- 1972年 アラン・ケイ、Smalltalkを発表。その設計を「オブジェクト指向」という言葉を使って説明する。
- 同年 デニス・リッチー、構造化に対応した言語、C言語を発表。
- 1983年 ビャーネ・ストロヴストルップ、Simulaの特徴を取り入れたC++言語を発表。

## 参考文献
- バードラント・メイヤー、オブジェクト指向入門　第2版 方法論・実践
    - P578 「Simulaの設計は［…］1967年に完成した。にわかには信じがたいことだが、構造化プログラミングの**前**に、Parnasが情報隠蔽についての記事を公表する前に、そして、「抽象データ型」が話題に上る何年も前に、完全なオブジェクト指向の言語が流行し、そして、実装されていた。」
【ethereum】ニーモニックor秘密鍵からキーストアを生成する

# 実装 #

早速ですが以下のライブラリを使用しました。
https://github.com/yamapyblack/ethereum-mnemonic-privatekey-exchanger

まずはクローンしてきて、必要なライブラリをインストールしていきます。

```
$ git clone https://github.com/yamapyblack/ethereum-mnemonic-privatekey-exchanger.git
$ cd /ethereum-mnemonic-privatekey-exchanger
$ npm install
```

## ニーモニックから秘密鍵orキーストアを生成 ##

exchangeByMnemonic.jsの以下を編集して実行します

```
const mnemonic = 'hoge fuga ...';
const password = 'Password123';
```

```
$ node exchangeByMnemonic.js
```

## 秘密鍵からキーストアを生成 ##

exchangeByPrivatekey.jsの以下を編集して実行します

```
const privatekey = '000...';
const password = 'Password123';
```

```
$ node exchangeByPrivatekey.js
```
Qiitaに投稿してみる ~Qiita記事の基本的な書き方~

#概要
「Qiita書くの楽しそうだし何か投稿してみたいっすね。」
趣味でプログラミング触ってるとQiitaにはよくお世話になる。
記事読んでいるうちに思考の整理とか備忘録として自分でも何か書いてみたくなる。
ただ何をどうすればいいのかよくわからないのだ。
「なんかMarkdownってやつ使うんだって」ぐらいの知識しかない。というかMarkdownって何?
そんな僕が踏み出す最初の一歩、練習がてら記事の書き方を投稿してみる。
「Qiitaに何か投稿してみたいけど何したらいいの?」って人の役に立ったりしたら嬉しい。

# Markdownって何?
>Markdown（マークダウン）は、文章の書き方です。
>[日本語Markdownユーザー会](https://www.markdown.jp/what-is-markdown/)

とのこと。それはそう。
どうやら見出しだとか文字の大きさだとか、そういう機能をHTMLとか勉強しなくても簡単に編集出来るようにしたぜってものらしい。便利。

#記事を書いていく
さて、ここからは記事の書き方をまとめていく。
今記事の書き方を調べながら得た知識をそのまま書いていく。

## 何が出来るようになりたいのか?
何が出来るようになれば見やすい記事が書けるのか考えてみた。
これが出来ればとりあえずOKかなと思う以下の5つについて自分なりに書き方を記述する。
1. [見出し] (#１見出し)
2. [引用] (#2引用)
3. [リンク] (#3リンク)
4. [ソースコード] (#4コード)
5. [目次] (#5目次)

###(1)見出し
この記事の[概要](#概要)とか[Markdownって何?](#markdownって何)みたいな太字でドドンと出てくる見出しの付け方について。
文頭に#と半角スペースを付けると見出しになるらしい。
ただ今試したら#の後ろの半角スペースはなくても見出しになった。環境によって違ったりするのか不明。あと#の数によって大きさが変わる。いっぱい付けるほど小さくなる。

### [記述]

~~~md
# 見出し
## 見出し
### 見出し
#### 見出し
##### 見出し
###### 見出し
####### 見出し
~~~

### [表示]
# 見出し
## 見出し
### 見出し
#### 見出し
##### 見出し
###### 見出し
####### 見出し

こんな感じ。#の数は6つで最小で7つ目以降の#は文字の大きさに関与しなかった。

###(2)引用
この記事の[Markdownって何?](#markdownって何)で使ってる引用について。
文頭に>を付ける引用になるらしい。
### [記述]

~~~md
>吾輩は猫である。
>>名前はまだ無い。
~~~

### [表示]
>吾輩は猫である。
>>名前はまだ無い。

こんな感じ。>>いっぱいつけると引用の引用になるっぽい。使いどころは不明。

###(3)リンク
この記事の[Markdownって何?](#markdownって何)で使ってるリンクについて。
こいつは[]内に記事タイトル()内にリンク先で記述出来るらしい。あと記事タイトルと別でリンクを記述したい時は<>で囲むと表記出来る。

### [記述]

~~~md
ex: [記事タイトル](リンク先URL)
[日本語Markdownユーザー会](https://www.markdown.jp/what-is-markdown/)
<https://www.markdown.jp/what-is-markdown/>
~~~

### [表示]
[日本語Markdownユーザー会](https://www.markdown.jp/what-is-markdown/)
<https://www.markdown.jp/what-is-markdown/>

こんな感じ。これで二通りのリンクの記述が出来た。

###(4)コード
Qiitaと言えばカコッイイコードがいっぱい。僕もあんなの書いてみたい。
これに関しては\~\~\~mdと\~\~\~でコードを囲む、または\~\~\~か\`\`\`でコードを囲むとカッコイイ表記になる。\~\~\~mdと\~\~\~のタイプはリンクの色とかが変わったりする。細かい性質は不明。

### [記述]
~~~
\~~~md
コード
\~~~
~~~
~~~
\~~~
コード
\~~~
~~~
~~~
\```
コード
\```
~~~

### [表示]

~~~md
コード
~~~

~~~
コード
~~~


```
コード
```

こんな感じ。ちなみに[記述]の方の\`とか\~の前に付いてる\は上手く囲えなかったから便宜的に付けたけど本当はついていないです。消し方がわからない。今後の課題です。

###(5)目次
[何が出来るようになりたいのか?](#何が出来るようになりたいのか)でやっている目次、というか今使っているページ内リンクの記述方法。これについては謎が多いのでテキトーに…
[]内に記事タイトル()内に#+リンク先で記述出来るらしい。#+リンク先については日本語・数字・小文字アルファベットが有効とのこと。多分だけど()内に記述したのに一致する#+見出しに飛んでくれるっぽい。

### [記述]
~~~md
[概要](#概要)に飛ぶ。
~~~

### [表示]
[概要](#概要)に飛ぶ。

こんな感じ。これについては挙動の理解が怪しい。まだ手探りで使っていくことになりそう。

#まとめ
色々と調べながら手探りで記事を書いてみた。まだ理解が怪しい部分もあるけれども最低限これが出来ればいいかなーってことは出来るようになった。
あとQiita記事タイトル横の・・・マーククリックすると「Markdownで本文を見る」って項目があるのでそこからMarkdownの記述方法参考にするとめちゃくちゃ便利。これからこれがやりたいってことが増えたらそこ参考にしていこうと思う。
最後にこの記事が「Qiita書いてみたいけどよくわかんないっす」って人の手助けになったりしたら幸いです。
それでは。
Windows10で無線profileをxmlファイルでエクスポート、インポートする方法

無線接続テストをするときに毎回端末にプロファイル設定するのが面倒くさかったので
何かないかと紛争したので、備忘録もかねて、、

一括で移行したい場合は↓

https://qiita.com/moomim/items/440f984c3da6865b1e54

#無線LANprofileのエクスポート

①コマンドプロンプトを[管理者]で起動する
 ※Windows+R　→　「cmd」と入力　→　ctrl+Shft+EnterでもOK

②　以下コマンドを入力し、
　　登録されている無線profileを確認する。

```ruby:実行コマンド
netsh wlan show profile
```
```ruby:実行例


C:\WINDOWS\system32>netsh wlan show profile

インターフェイス Wi-Fi のプロファイル:

グループ ポリシー プロファイル (読み取り専用)
---------------------------------------------
    <なし>

ユーザー プロファイル
---------------------
    すべてのユーザー プロファイル     : test-ssid
    すべてのユーザー プロファイル     : hogehgoe


C:\WINDOWS\system32>

```


③　以下コマンドを入力し、profileをエクスポートする。

```ruby:実行コマンド
netsh wlan export profile name="プロファイル名" folder=出力先パス
```
```ruby:実行例
C:\WINDOWS\system32>netsh wlan export profile name="test-ssid" folder=C:\

インターフェイス プロファイル "test-ssid" がファイル "C:\Wi-Fi-test-ssid.xml" に保存されました。


C:\WINDOWS\system32>
```

#無線LANprofileのインポート
④　以下コマンドを入力し、インポートを実施する。

```ruby:実行コマンド
netsh wlan add profile filename="エクスポートしたxmlのファイルパス"
```
```ruby:実行例　

C:\WINDOWS\system32>netsh wlan add profile filename="C:\Wi-Fi-test-ssid.xml"
プロファイル test-ssid がインターフェイス Wi-Fi に追加されます。

C:\WINDOWS\system32>
```
#無線LANprofileの削除

⑤　以下コマンドを入力し、profileの削除を実施する。

```ruby:実行コマンド
netsh wlan delete profile name="プロファイル名"
```
```ruby:実行例　
C:\WINDOWS\system32>netsh wlan delete profile name="test-ssid"
プロファイル "test-ssid" がインターフェイス "Wi-Fi" から削除されます。

C:\WINDOWS\system32>
```
```ruby:削除後

C:\WINDOWS\system32>netsh wlan show profile

インターフェイス Wi-Fi のプロファイル:

グループ ポリシー プロファイル (読み取り専用)
---------------------------------------------
    <なし>

ユーザー プロファイル
---------------------
    すべてのユーザー プロファイル     : hogehgoe

```
[js]return falseについてメモ


##バブリング
HTML要素で子要素から親要素へイベントが伝播していくこと
####下の例ではchild要素をクリックすると親要素のクリックイベントも発火する
```
<div id="parent" onClick="parentFunc()">
  <div id="child" onClick="childFunc()">
  </div>
</div>
```

####簡単な対象法として jqueryのreturn false
htmlでonClickつけるのをやめて

```
$('#parent').click(function(){

　処理
　
});

$('#child').click(function(){
  処理
　return false;
});

```
WordPressの自動更新(アップデート)を有効化する方法

##はじめに

WordPressの本体やテーマ・プラグインを常に最新バージョンに更新しておくことは、重要なセキュリティ対策となります。

というのも、ハッカーは古いバージョンで見つかった脆弱性を狙って不正アクセスを仕掛けてくるため、脆弱性が修正されている最新バージョンにしておけば防げるからです。

この記事では、簡単なカスタマイズにより、WordPressの本体・テーマ・プラグインを自動更新する設定方法を紹介します。

##WordPressの自動更新を有効化する方法

WordPressのfunction.phpに以下のコードを設置してください。
管理画面から、外観→テーマエディター→テーマファイルで編集できます。

```function.php
//本体のメジャーアップデートの自動更新を有効化
add_filter( 'allow_major_auto_core_updates', '__return_true' );

//本体のマイナーアップデートの自動更新を有効化
add_filter( 'allow_minor_auto_core_updates', '__return_true' );

//テーマの自動更新を有効化
add_filter( 'auto_update_theme', '__return_true' );

//プラグインの自動更新を有効化
add_filter( 'auto_update_plugin', '__return_true' );
```

上記コードは、WordPress本体のメジャーアップデート・マイナーアップデート・テーマ・プラグインの全ての自動更新を有効化する設定となります。

自動更新を無効化したいものがある場合は、`__return_true`となっている箇所を`__return_false`に変更すれば無効化できます。

##参考ページ

[自動バックグラウンド更新の設定](https://wpdocs.osdn.jp/自動バックグラウンド更新の設定)
ArcGIS Runtime SDK：AR (拡張現実) ツールキットと Xamarin によるビルドとデプロイ手順のご紹介

AR アプリについて書きました。
Xamarin による iOS と Android のビルドとデプロイ手順も紹介しています。

ArcGIS Runtime SDK：AR (拡張現実) ツールキットと Xamarin によるビルドとデプロイ手順のご紹介
https://community.esri.com/docs/DOC-15422
AndroidのViewを回転させ続ける方法

```SampleFragment.kt
    private fun rotateLoadingImage() {
        // 画像の中心を軸に回転させる
        val rotate = RotateAnimation(
            0f,
            360f,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f
        )
        // 一回転にかかる時間(ms)
        rotate.duration = 3000
        // 回転速度を一定にする
        rotate.interpolator = LinearInterpolator()
        // 無限リピート
        rotate.repeatCount = Animation.INFINITE
        // ImageViewのstartAnimationメソッドを呼び出す
        image_loading.startAnimation(rotate)
    }
```
《未経験→webエンジニア》実務4日目

## 【今日やったこと】
APIテスト
SQL文の学習

## 【知らなかったこと】

「クエリ」は、データベースなどへの要求を文字列で表したもの。 「SQL」は、データベースへ問い合わせるための言語仕様。

内部結合は、先にAテーブルの指定カラムを拾った後にBのテーブルを結合する※重なる部分だけ
外部結合は、テーブルを左か右で指定して、その指定したテーブルを基準に結合する※重ならない部分も！
参考URLhttps://qiita.com/naoki_mochizuki/items/3fda1ad6594c11d7b43chttp://www.pursue.ne.jp/jouhousyo/SQLDoc/select22.html

・MinIO
S3の互換ツールのイメージ。Docker上で動かせて、コストもかけずにお試しできるので便利らしい※S3だと画像をgitに入れてしまうと重くなってしまうのも難点
参考URLhttps://dev.classmethod.jp/articles/s3-compatible-storage-minio/

・冗長な構成冗長構成とは、情報システムなどの構成の一種で、設備や装置を複数用意し、一部が故障しても運用を継続できるようにしたもの。システムなどが持つそのような性質を「冗長性」、そのような構成法を「冗長化」という。
## 【明日】やるべきこと、読みたい記事など
CarrierWaveで「Nil location provided. Can't build URI.」が出た時の対処法

## 環境
```
ubuntu(wsl)
Rails 6.0.3
ruby 2.5.1
CarrierWave
```

## 想定状況と原因

エラーの箇所がこちら

```view/user/show.html.slim
 = link_to image_tag(user.image.url), user
```

一旦Userモデルの中身を調べてみます。
↓Userモデルの中身

```
name: "藤田 翔太",
  email: "jeromy_weimann@wehner.info",
  password_digest: [FILTERED],
  admin: false,
  image: nil,
```

`image`の値が`nil`になっているのが原因のようです。

## 解決策
#### 解決策１.  nilとなっているユーザーを削除する。
`rails c`などでnilになっているユーザーを探して削除する。

#### 解決策2. デフォルト画像の設定をする
`image_uploader.rb`に以下を追加します。

```app/uploaders/image_uploader.rb
  def default_url(*args)
    'default.png'
  end

```
`app/assets/images`に画像を置いたら終わりです。

### 参考文献
- [【Rails】image_tagの基本とデフォルト画像の設定方法](https://qiita.com/Akitoshi_M/items/a6382efd410fe5544406)
[Outlook2010まで]Outlook で自動仕訳ウィザードのスクリプトを作成する方法

この方法はOutlook2013以降は使えない機能になっています。
セキュリティの強化のためとされています。
もっとも全く使えないわけではなく、レジストリを設定すれば動きます。
もうすぐOutlook2010のページもみな日本語がなくなり、忘れ去られてしまうでしょう。
しかし、サブルーチンでは全く意味がわかりません。

[Outlook で自動仕訳ウィザードのスクリプトを作成する方法](https://docs.microsoft.com/ja-jp/previous-versions/office/troubleshoot/office-developer/create-script-for-rule-wizard-in-outlook)
2020/03/18
適用対象:Microsoft Outlook 2010, Microsoft Office Outlook 2003
#概要

Outlook の自動仕訳ウィザードを使用すると、特定のルールを作成するときに "スクリプトを実行" することができます。 これにより、開発者は、自動仕訳ウィザードの通常の機能を使用するときでも、受信メールに対してVBA~~アクション~~を実行することができます。
#詳細
##重要

<font color="darkblue">自動仕訳ウィザードはカスタムコードを "script" として参照しますが、Microsoft Visual Basic Scripting Edition (VBScript) や Microsoft JScript などの他のスクリプト言語ではなく、Outlook Visual basic for Applications でコードを作成する必要があります。 また、Outlook Visual Basic for Applications は展開するように設計されていないため、このカスタムコードを展開するには、各ユーザーのコンピューターに手動で構成する必要があります。 Outlook.COM アドインでカスタムコードを作成することはできません。 Visual Basic for Applications プロジェクトの配布に関連する制限の詳細については、以下の記事番号をクリックして、Microsoft サポート技術情報の記事を参照してください。</Font>

290779 Outlook 2002 Visual Basic for APPLICATIONS (VBA) プロジェクトの管理と配布に関する説明
<details><summary>(中略)</summary><font color="Blue">Microsoft では、特定の目的のために、明示的にも黙示的にも、または特定の目的のための適合性の黙示的な保証を含め、明示されているかどうかにかかわらず、説明のためのプログラミング例を提供しています。 この記事では、使用するプログラミング言語と、手順を作成してデバッグするためのツールについて理解していることを前提としています。 Microsoft サポート担当者は、特定の手順の機能について説明しますが、特定のニーズに合わせて追加機能を提供したり、プロシージャを作成したりすることはありません。
プログラミングの手順が制限されている場合は、Microsoft 認定パートナーまたは Microsoft アドバイザリーサービスにお問い合わせください。</font></details>

メッセージを処理するカスタムコードを実装するには、Visual Basic for Applications で~~サブルーチン~~Subプロシージャ<sup id="fnref1"><a href="#fn1" rel="footnote" title="サブルーチンとなっているがSubプロシージャ">1</sup>を作成します。 Subプロシージャの名前は重要ではありませんが、自動仕訳ウィザードが電子メール (MailItem) または会議出席依頼 (MeetingItem) をSubプロシージャに渡すため、1つの引数を受け取る必要があります。 引数は MailItem または MeetingItem 型である必要があります。それ以外の場合、このSubプロシージャを自動仕訳ウィザードで使用できません。<sup id="fnref2"><a href="#fn2" rel="footnote" title="住所やNoteItemは不可。この2種類以外はできない。しかし会議出席依頼もMailItemの変種なので、事実上MailItemしか効かない">2</sup>
 Object 型の引数を定義することにより、両方の種類のアイテムを処理する1つのSubプロシージャを作成することはできません。<sup id="fnref3"><a href="#fn3" rel="footnote" title="`Sub CustomMailMeetingRule(oItem As Object)`のような記述は不可">3</sup> 次の Outlook Visual Basic for Applications コードは、Subプロシージャの作成方法を示しています。<sup id="fnref4"><a href="#fn4" rel="footnote" title="メールや会議出席依頼（これもメールの一種）がきたときにメッセージボックスがポップアップして通知する">4</sup>

```vb:vba
Sub CustomMailMessageRule(Item As Outlook.MailItem)
   MsgBox "Mail message arrived: " & Item.Subject
End Sub

Sub CustomMeetingRequestRule(Item As Outlook.MeetingItem)
   MsgBox "Meeting request arrived: " & Item.Subject
End Sub
```
<ol>
<li id="fn1">
<p>サブルーチンとなっているがSubプロシージャ&nbsp;<a href="#fnref1">↩</a></p>
</li>
<li id="fn2">
<p>住所やNoteItemは不可。この2種類以外はできない。しかし会議出席依頼もMailItemの変種なので、事実上MailItemしか効かない&nbsp;<a href="#fnref2">↩</a></p>
</li>
<li id="fn3">
<p>`Sub CustomMailMeetingRule(oItem As Object)`のような記述は不可↩&nbsp;<a href="#fnref3">↩</a></p>
</li>
<li id="fn4">
メールや会議出席依頼（これもメールの一種）がきたときにメッセージボックスがポップアップして通知する↩&nbsp;<a href="#fnref4">↩</a></p>
</li>
</ol>
VSCodeでスペルミスを指摘してくれるCode Spell CheckerをRuby言語に対応させる

#はじめに
VSCodeの拡張機能のCode Spell Checkerはスペルミスを指摘してくれる便利な機能ですが初期設定ではRuby言語には対応しておらず、自分で設定しないと動作しません。
この記事ではその設定方法を紹介したいと思います。

#背景
Railsチュートリアルで学習を進めている時に`rails test`でよくエラーになっていたのですが、そのほとんどがスペルミスによるものでした。
そこでスペルミスをチェックしてくれるCode Spell Checkerという拡張機能を知り、インストールしてみたものの機能しませんでした。
どうやら初期設定ではRubyには対応していないということなので、設定で追加する方法を調べてみました。

Code Spell Checkerをインストールしたけど言語が対応していなくて困っている方を対象にこの記事を書きました。

###動作環境
macOS Catalina バージョン: 10.15.6
VSCode バージョン: 1.49.0
Code Spell Checker バージョン: 1.9.0

#設定方法
流れとしては`settings.json`ファイルに`cSpell.enabledLanguageIds`を使って言語を追加します。

まずは`settings.json`のファイルの開き方。
`command+カンマ(,)`で設定画面を開きます。
設定画面の右上にあるアイコンをクリックして`settings.json`のファイルを開きます。
![vscodeの設定画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/724484/52504450-df2f-3eb1-12d2-77ccdc9c8fdc.png)

あとは`settings.json`のファイルに`"cSpell.enabledLanguageIds":["言語"]`を追加するだけです。


```settings.json
    "cSpell.enabledLanguageIds": [
            "css",
            "html",
            "javascript",
            "json",
            "less",
            "markdown",
            "plaintext",
            "scss",
            "text",
            "ruby",
            "yaml",
            "yml"
          ],
```

![settings_json.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/724484/92c8c646-e34d-e91d-bb59-150f3f21941e.png)

#まとめ
これで追加した言語のファイルにもCode Spell Checkerが動作するようになりました。
詳しくはCode Spell Checkerのサイトに書いてあるので見てみてください。
[Code Spell Checker - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker "Code Spell Checker - Visual Studio Marketplace")
MySQLの設定で、許可するポートを変更する。

MySQLで許可するポートを変更する。
今回はポート`33069`を許可する。

## 1. 設定

MySQLをインストールしたインスタンスにSSH接続する。

```
# vi /etc/mysql/mysql.conf.d/mysqld.cnf
```

```/etc/mysql/mysql.conf.d/mysqld.cnf
# port            = 3306
```
この行を下記に変更する。

```/etc/mysql/mysql.conf.d/mysqld.cnf
port            = 33069
```

MySQLを再起動する。

```
sudo service mysql restart
```

## 2. 確認

外部インスタンスからMySQLへの疎通を確認する。
外部インスタンスへSSH接続し、下記のコマンドを実行します。

```
$ mysqladmin ping -h xxx.xxx.xxx.xxx --port 33069 -u username -p
Enter password:
```

MySQLのusernameのパスワードを入力してEnter。

```外部インスタンス
mysqld is alive
```
疎通できているならこんな風になる。
FileMakerProのプレースホルダテキストで時刻入力例を表示

# はじめに
## 対象読者
* FileMaker Pro ユーザー
* フィールドのプレースホルダテキストで時刻の入力例を入れたい人

## どういうの？
* こういうの

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37739/c6cf8e36-f081-71d7-2374-dddf75bf4b48.png)

* インスペクタのここから設定できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37739/2f2cb2ff-2c6b-b831-f43e-e270b63a313d.png)


## 基本の要件
* hh:mm の形式
    * つまり時刻表示は zero padding ( 一桁数値の場合の十の位を 0 にする)
* プレースホルダテキストは返値が「テキスト」型

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37739/1200a99f-5f95-3b00-c3e4-4fbfc707216b.png)


# 本題
## 開始時刻の表示
### 要件
* 現在時刻を表示する

```
Right ( "0" & Hour ( Get ( 時刻 ) ) ; 2 ) & ":" &
Right ( "0" & Minute ( Get ( 時刻 ) ) ; 2 )
```

## 終了時刻の表示
### 要件
* 現在時刻の二時間後を表示する

```
Right ( "0" & Hour ( Get ( 時刻 ) + Time ( 2 ; 0 ; 0 ) ) ; 2 ) & ":" &
Right ( "0" & Minute ( Get ( 時刻 ) ) ; 2 )
```

## 結果
* 最初にお見せしたとおり、こうなります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37739/c6cf8e36-f081-71d7-2374-dddf75bf4b48.png)


# おわりに
* もっと良い書き方あったら教えてください 🙏
createMaterialBottomTabNavigatorの使い方



公式では使い方が全くもって分からなかったのサンプルのコードを自分で作りました。


<h4>Navigation.js</h4>
<pre>
import React, { Component } from 'react';
import { Platform } from 'react-native';
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
import { createAppContainer } from 'react-navigation'; 

import Hoge1 from './hoge1';
import Hoge2 from './hoge2';
import Hoge3 from './hoge3';

 const TabNavibar = createMaterialBottomTabNavigator(
  {
    example1: {
      screen: Hoge1,
      navigationOptions: {
        tabBarLabel: 'example1',
        tabBarColor: '#842655',
        tabBarIcon: ({ tintColor, focused }) => (
          &lt;Icon size={25} name={ Platform.OS === 'ios' ? (focused ? 'ios-home' : 'ios-home') : 'md-home' } style={{ color: tintColor }} />
        )
      }
    },
    example2: {
      screen: Hoge2,
      navigationOptions: {
        tabBarLabel: 'example2',
        tabBarColor: '#1e1e1d',
        tabBarIcon: ({ tintColor, focused }) => (
          &lt;Icon size={25} name={ Platform.OS === 'ios' ? (focused ? 'ios-contact' : 'ios-contact') : 'md-contact' } style={{ color: tintColor }} />
        )
      }
    },
    example3: {
      screen: Hoge3,
      navigationOptions: {
        tabBarLabel: 'example3',
        tabBarColor: '#ff3838',
        tabBarIcon: ({ tintColor, focused }) => (
          &lt;Icon size={25} name={ Platform.OS === 'ios' ? (focused ? 'ios-settings' : 'ios-settings') : 'md-settings' } style={{ color: tintColor }} />
        )
      }
    }
  },
  {
    shifting: true,
    activeTintColor: 'white',
    inactiveTintColor: '#ddd',
  }
);

export default createAppContainer(TabNavibar);
</pre>

<h4>MainNavigation.js</h4>
<pre>
import React from 'react';
import { StatusBar } from 'react-native';
import { NavigationContainer } from "@react-navigation/native";
import MyTabs from './TabNavigator';

class MainNavigator extends React.Component {
  constructor(props) {
    super(props);
  }

  render () {
    return(
      &lt;NavigationContainer>
        &lt;StatusBar />
        &lt;MyTabs /> 
      &lt;/NavigationContainer>
    );
  }
}

export default MainNavigator;
</pre>


今回はMainNavigationの中にさらにNavigationを作る方向で書きました。
Hoge: コンポーネントの名前です。
example1, example2, example3: ルーティングの名前です。分かりやすいようにtabBarLabelと合わせた方がいい気がします。
screen: 遷移したいコンポーネントの名前
tabBarLabel: アイコンの下に表示するタイトル

アイコンに関しては
https://oblador.github.io/react-native-vector-icons/
に載っています。

各コンポーネントに通すものはありません。navigationも通さなくていいです。
RubyのStringIOから値を回収する

Rubyには、ファイルに書き出すと見せかけて文字列を生成する、`StringIO`というクラスがあります。便利に使えるのですが、少しハマった箇所がありました。

## `StringIO`とは

まず、ファイルやパイプなどに対して読み書き、ファイル内の位置移動などを司る`IO`というクラスがあります。読み書きを行うメソッドが、実際に出力する先を`IO`で取るようにすれば、実際のアクセス先がどこであろうと利用可能です。

これに対して、`StringIO`は、`String`を`IO`のインターフェースで扱えるようにしたものです。引数として`IO`を取るメソッドに`StringIO`を渡せば、値を文字列として回収できます。

なお、`StringIO`と`IO`の間に継承関係はなく、ダックタイピングとして実装されています。

## 値の回収に失敗する例

ということで、`StringIO`で値を取得しようとしたのですが、失敗したことがありました。

```rb:失敗例
sio = StringIO.new
SomeAPI.download(key, output: sio)
data = sio.read
```

`IO`だから`read`すればいいと思ったのですが、これでは`data`に取れる値は空文字列となってしまいます。

## 失敗の要因と改善策

失敗の要因ですが、`StringIO`は現在の位置も記録しているので、追記を繰り返して`StringIO`へ書き出した場合、位置が末端に来ています。そのまま`read`を行っても、すでに末端にいるので何も取れません。

もちろん`rewind`してから`read`でもいいのですが、そんなことをしなくても、`StringIO#string`を使えばバッファとして持っている文字列をそのまま得ることができます。

## 外部リンク

* [class StringIO - るりま](https://docs.ruby-lang.org/ja/latest/class/StringIO.html)
django rest frameworkで認証したアカウント情報を返す時に 401と返って来て詰まった箇所。

現在djangoで作ったポートフォリオをspaに変換して作っていて、
最近ようやく思った挙動をしてくれたので、それでかなり詰まった箇所を備忘録として書いていこうと思います。


######開発環境

@nuxt/cli v2.13.3

```requirements.txt
Django>=2.0,<3.0
psycopg2>=2.7,<3.0
Pillow>=7.1.2
djangorestframework>=3.11.0
django-filter>=0.11.0
django-cors-headers>=3.0.0
djangorestframework-jwt>=1.11.0
djoser == 2.0.1
djangorestframework-simplejwt>=4.4.0
```

コンポーネントでログインページを作り、作ったページのurlをconfig.jsに渡しました。

```nuxt.config.js
axios: {

      baseURL: "http://0.0.0.0:8000"
      //proxy: true
    },


auth: {
      redirect: {
        login: { url: '/chat', method: 'post', propertyName: 'token' },
        logout: { url: '/', method: 'post' },
        callback: false,  
        home: '/chat',      
      },
      strategies: {
        local: {
          endpoints: {
            login: { url: '/api/login/', method: 'post', propertyName: 'token' },
            user: { url: '/api/auth/users/me/', method: 'get', propertyName: false },
            logout: false
          },
        }
      }
    }
```


```
error
get http://0.0.0.0:8000/api/auth/users/me/　401
```


と出てくるので色々模索したら

どうやらapiの方に問題があったみたいです。

https://stackoverflow.com/questions/33265812/best-http-authorization-header-type-for-jwt
このページによると



> クライアントがアクセストークン（JWTまたはその他のトークン）を送信するのに最適なHTTPヘッダーは> Authorization、Bearer認証スキームを含むヘッダーです。
>
> このスキームはRFC6750で説明されています。

とのこと。

```settings.py
JWT_AUTH = {
    'JWT_VERIFY_EXPIRATION': False,
    'JWT_AUTH_HEADER_PREFIX': 'Bearer', #変更前はJWT
}
```

と直したら動きました。
FutureBuilder 使用時に `Snapshot has neither data nor error`とエラー発生

FutureBuilder 使用時に `Snapshot has neither data nor error`とエラー発生

---

- 環境
  - Dart SDK version: 2.9.2 (stable) (Wed Aug 26 12:44:28 2020 +0200) on "macos_x64"
  - Flutter 1.20.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 216dee60c0 (2 weeks ago) • 2020-09-01 12:24:47 -0700
Engine • revision d1bc06f032

## □ エラー内容

```bash:
...snip

════════ Exception caught by widgets library ═══════════════════════════════════
The following StateError was thrown building HomepageFeaturedWidget(dirty):
Bad state: Snapshot has neither data nor error

...snip
```


## □ 問題のコード

```dart:
  Container(
	child: FutureBuilder<List<Series>>(
	  future: seriesList,
	  builder: (context, snapshot) {
		return HomepageFeaturedWidget(snapshot: snapshot);
	  },
	),
  ),
```


## □ 解決策
- `seriesList` は `Future<T>` であることから、非同期でデータを取得
- そのため、Widget 生成直後は `HomepageFeaturedWidget` の引数が空であるため、エラーが発生した様子
- このことから snapshot を未取得時に対する処理を追加


```diff:
  Container(
	child: FutureBuilder<List<Series>>(
	  future: seriesList,
	  builder: (context, snapshot) {
+       if (!snapshot.hasData) {
+         return const Center(child: CircularProgressIndicator());
+       }

		return HomepageFeaturedWidget(snapshot: snapshot);
	  },
	),
  ),
  // ...snip	
```


### □ メモ

[公式サイト](https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html)を参照すると、`取得時、例外時、未取得時`で処理を分割


```dart
  if (snapshot.hasData) {
  	// ...snip
  } else if (snapshot.hasError) {
  	// ...snip
  } else {
  	// ...snip
  }
```
raspberry pi3B+ M5stackとSerial通信

# raspberry pi3BでSerial通信

マイコンを使用してのシステム開発でデータベースを使いたい
Reactjsなどフロントエンドなどと連携させたいときラズパイは、非常にコスパがいい機材です。

しかし、ラズパイは、ルータの性能によるのか？Wi-Fi通信に若干の不安があります。
なので、ラズパイに生えているピンに物理的に線で接続して通信できるSerial通信をやろうと思います。

##　機材
* M5stack
* raspberry pi3B
* 作業用PC
* ジャンパー線　2本

## 使用言語
* Arudino
* python3


## 準備
pythonの使用するライブラリはpyserialです。

```cmd
pip3 install pyserial
```

次にラズパイの設定です。
Serial通信できるようにする設定を行います。

```cmd
sudo raspi-config

Interfacing Options　を決定
P6 Serial　を決定
Would you like a login shell to be accessible over serial? 　”いいえ” を決定
Would you like the serial port hardware to be enabled? 　”はい” を決定
```
これで、ピンが使えるようになったはずです。

## やってみようSerial通信
今回確認用でM5stackを使用します。

```c:M5stack_serial_catch.ino
#include <M5Stack.h>

int half_Height, half_Width = 0;
void setup() {
  Serial.begin(115200);
  M5.begin();
  half_Height = M5.Lcd.height() / 3;
  half_Width = M5.Lcd.width() / 5;
  M5.Lcd.setTextSize(5);

}

void loop() {

  if ( Serial.available() > 0 ) {
    String str = Serial.readStringUntil('\n');
    Serial.print("M5:");
    Serial.println(str);
    M5.Lcd.drawString(str, half_Width, half_Height);
  }
  delay(1000);
}
```

```python3:Serial_test.py
import serial

print("start")
ser = serial.Serial('/dev/ttyS0',115200)
print("send")
ser.write(b'Hello World')
c =ser.read(20)
print(c)
ser.close()
```

### 詰まった個所
raspberry pi の仕様で”ttyS0”を"ttyAMA0"にしていたせいで送れていないということがありました。変な勘違いをしてしまいました。
ttAMA0は、bluetoothに使用されているそうです。

## あとがき
インターネットの情報は、断片的なので苦労しました。
確認用でM5stackを使用したのは、ボタンがついているからです。
ボタンを押してSerialで伝達すれば簡単にpythonの動作を制御できると考えたからです。
あと、画面があってわかりやすいと考えました。

ラズパイはセンサーをつけたりNFCを接続したりで学習には、もってこいの機材ですね！
Cloud Run Go echoへの Cloud Schedulerからのリクエストで415エラー

掲題のとおりCloud Runで以下のエラーが発生

```
POST 415 324B 389ms Google-Cloud-Scheduler
```

[echo](https://echo.labstack.com/)はGoのwebフレームワーク
path parameterを使いたくて利用

echoのエラーログは以下

```
error: code=415, message=Unsupported Media Type
```

`Unsupported Media Type` とのことなのでContent-Typeが原因っぽい

# 結論

Cloud scheduler からくるリクエストヘッダはGUIから設定すると`Content-Type`が設定されず、
`echo.Context.Bind`を使ったリクエストのパースをすると上記エラーが発生する

# 事象発生環境

- go 1.14
- echo 3.3.10

## echo リクエストパース部分

`Content-Type: application/json`を想定していたのでリクエストボディのjsonを読み込んでstructにする部分を下記のように実装してCloud Runにデプロイ

``` go
Message struct {
    RoomNames []string `json:"RoomNames"`
}

func Handler(c echo.Context) error {
	var m Message
	m := new(Message)
	if err := c.Bind(m); err != nil {
		return err
	}
...
}
```

下記のcurlでは成功

`curl -H "Content-Type: application/json" -d '{"RoomNames":["living", "study"]}'`

## Cloud Schedulerの設定

HTTPメソッドをPOSTで下記Bodyを設定

`{"RoomNames":["living", "study"]}`

上記415エラーが発生

# 解決

`gcloud scheduler jobs update http` のオプションで `--update-headers=Content-Type=application/json` をつけてリクエストヘッダを変更する


もしくは以下

echo リクエストパース部分を下記の通り変更したところCloud Schedulerからリクエストしても成功するようになった

``` go
func Handler(c echo.Context) error {
	var m Message
	b, err := ioutil.ReadAll(c.Request().Body)
	defer c.Request().Body.Close()
	if err != nil {
		log.Printf("ioutil.ReadAll: %v", err)
		return echo.ErrBadRequest
	}
	if err := json.Unmarshal(b, &m); err != nil {
		log.Printf("json.Unmarshal: %v", err)
		return echo.ErrBadRequest
	}
}
```

# おわり

Cloud Schedulerの設定GUIにはヘッダを設定する場所がなく、勝手に`Content-Type`が付いてるもんだと思ってた
単なる思い込み
ヤフーニュースやはてなブックマークみたいな、コメント付きニュースサイトを作りたい

#コメントを集めるには？
コメントを集めるのって、至難の業ですよね。
少し考えたのですが、Twitterからニュースをツイートしているコメントから、
抜き取ればいいんじゃないかと閃きました💡
PythonでTwitterのニュースに対する、コメントを抽出しました。

```
import tweepy
import re
from collections import Counter
import unicodedata
import string

consumer_key    = "twitterapiのconsumer_key"
consumer_secret = "twitterapiのconsumer_secret"

auth = tweepy.AppAuthHandler(consumer_key, consumer_secret)
api = tweepy.API(auth)

title = "ニュースのタイトル"
url = "ニュースのURL"
site_domain_name = "配信元"

title1 = r"" + re.escape(title) + r"(.|\s)*#\S+(\s|$)"
title2 = r"" + re.escape(title) + r"\s(.{0,40})https?://[\w/:%#\$&\?\(\)~\.=\+\-]+"
title3 = r"" + re.escape(title) + r"(.{0,40})https?://[\w/:%#\$&\?\(\)~\.=\+\-]+"
title4 = r"" + re.escape(title)

tweets = api.search(url, count=100, exclude='retweets', tweet_mode='extended', lang = 'ja', result_type='recent')

for tweet in tweets:
    text = re.sub(title1, "", tweet.full_text)
    text = re.sub(title2, "", text)
    text = re.sub(title3, "", text)
    text = re.sub(title4, "", text)
    text = re.sub(r'（(.*?)）', "", text)
    text = re.sub(r'\((.*?)\)', "", text)
    text = re.sub(r'【(.*?)】', "", text)
    text = re.sub(r'\[(.*?)\]', "", text)
    text = re.sub(r'〔(.*?)〕', "", text)
    text = re.sub(r'#\S+(\s|$)', "", text)
    text = re.sub(r'＃\S+(\s|$)', "", text)
    text = re.sub(r'@[a-zA-Z0-9_]+さんから', "", text)
    text = re.sub(r'@[a-zA-Z0-9_]+さん', "", text)
    text = re.sub(r'@[a-zA-Z0-9_]+から', "", text)
    text = re.sub(r'@[a-zA-Z0-9_]+より', "", text)
    text = re.sub(r'｜(.*)(\s|$)', "", text)
    text = re.sub(r'\|(.*)(\s|$)', "", text)
    text = re.sub(r'-\s(.*)(\s|$)', "", text)
    text = re.sub(r'■(.*)(\s|$)', "", text)
    text = re.sub(r'@[a-zA-Z0-9_]+', "", text)
    text = re.sub(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-]+', "", text)
    text = text.replace("【","").replace("】","").replace("＞","").replace("／","").replace(":","").replace("：","").replace("/","").replace("|","").replace(".","").replace("“","").replace("”","")
    text = text.replace("via","")
    text = text.replace(site_domain_name,"")
    lists = title.split(" ")
    for list in lists:
        text = text.replace(list,"")
    text = text.lstrip()
    text = text.rstrip()
    comp_a = unicodedata.normalize("NFKC", text)
    table = str.maketrans("", "", string.punctuation  + "「」、。・！")
    comp_a = comp_a.translate(table)
    comp_b = unicodedata.normalize("NFKC", title)
    table = str.maketrans("", "", string.punctuation  + "「」、。・！")
    comp_b = comp_b.translate(table)
    if text != "" and len(text) > 1 and comp_a not in comp_b:
        print(text)
```
#完成したニュースアプリ
![IMG_2174.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/c1077d64-57eb-6ddc-7c23-5feddb5d689f.png)
![IMG_2176.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116361/921836b8-f7d1-ab9e-85c6-f59bf63da1c6.png)

NewsTweet（ニューズツイート）
https://apps.apple.com/jp/app/newstweet-ニューズツイート/id1531315934
Flutter で Swift のライブラリがリンクされずにビルド失敗する

# 問題
Flutter でプラグイン（ネイティブ実装）を含む新しいパッケージを使うようにしたら、突然 Swift 関係のリンクエラーでビルド失敗することがあります。

```
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ld: warning: Could not find or use auto-linked library 'swiftCoreLocation'
    ld: warning: Could not find or use auto-linked library 'swiftCoreFoundation'
    ld: warning: Could not find or use auto-linked library 'swiftCompatibility50'
    ld: warning: Could not find or use auto-linked library 'swiftFoundation'
...
```

# 原因
flutter create -i objc で作成した Flutter アプリから、Swift コードを含むパッケージを参照すると、この問題が発生します。Swift 関係のライブラリの参照設定が全く行われていないからです。

flutter create 時に Swift （デフォルト）が選択されていればこの問題は発生しません。

# 解決
Flutter の Runner ワークスペース（ios/Runner.xcworkspace) を開いて、何か1つ Swift のコードを追加してやれば治ります。

1. Xcode を使って、ios/Runner.xcworkspace を開きます。
2. New File... メニューを使って何か１つダミーの Swift ファイルを追加します。
3. 「Swift - ObjC 間の Briding-Header.h を作るか」と尋ねられるので、「YES」を選択してヘッダを生成させます。
テーブルにコメントを付ける

テーブルにコメントを付ける構文はMySQL(MariaDB)とPostgreSQLとで異なる。

# MySQL(MariaDB)

```sql
-- MySQL(MariaDB)
-- ALTER TABLE <テーブル名> COMMENT "<コメント>";
ALTER TABLE items COMMENT "商品テーブル";
```
# PostgreSQL

```sql
-- PostgreSQL
-- COMMENT ON TABLE <テーブル名> IS "<コメント>";
COMMENT ON TABLE items IS "商品テーブル";
```
基本情報技術者試験を受けた

# 基本情報技術者試験(FE)とは
情報処理技術者試験は、「情報処理の促進に関する法律」に基づき経済産業省が、情報処理技術者としての「知識・技能」が一定以上の水準であることを認定している国家試験です。
　情報システムを構築・運用する「技術者」から情報システムを利用する「エンドユーザ（利用者）」まで、ITに関係するすべての人に活用いただける試験として実施しています。特定の製品やソフトウェアに関する試験ではなく、情報技術の背景として知るべき原理や基礎となる知識・技能について、幅広く総合的に評価しています。
（IPAのHPより引用）
<https://www.jitec.ipa.go.jp/1_08gaiyou/_index_gaiyou.html>

## 基本なのか
基本と言っても良いレベルで、試験の勉強前後では社内ミーティング等で出てくる技術的な話題に置いて行かれることはなくなった。
しかし、あくまで概念的な面が主で、プロダクトごとには自分で調べる必要がある。
例えばDBに関して、基礎知識は得られても、具体的な「MySQLとDB2の違い」とかの話題になるとそこは個別の知識が必要になってくる。
ただ、ミーティング内で「DB接続の際はデッドロックに気をつけて～～」とか汎用的な用語に関しては詰まることはないと思う。

## 弊社での取得率(肌感)
開発部門の人だけで換算しても、6割前後くらいといった感じ。
取っていない人の中でも、取れるけど面倒な人と、普通に取れない人が混在している。
きちんと計測したわけではないが、周囲の印象としてはこんなレベル。

# 勉強したこと
・テキスト読む
・過去問を解く
・過去問を再び解く
・過去問を再び解く
（以下繰り返し）
## 勉強時間
大体、30時間前後？
## 勉強内容
テキストを全部読んでから、過去問を繰り返し解いた。
理解して解けた問題は、次回以降適当に解いて、解けなかった問題について重点的に復習。
3年間の春秋で計6回分。一周には3時間もあれば終わる。
正直、一週目以降は問題文はそこまで読んでないです。
一周したら、問題の主旨が分かると思うので、それに合った知識を埋めていく感じ。
解けなかった分に関しては、周辺の知識も一緒に覚えていくと良いかもしれない。
例えば、RAIDについて聞かれた問題を間違えたなら、RAID5とかまで覚える感じです。

# 総括
これに受かったからつよつよエンジニアになれるとは思えないが、つよつよエンジニアになるためには、これに余裕で受からないと無理だろうなって感じでした。
## 受けた方が良いか
IT全く分かりませんって人なら受ける意味はあると思います。
ただ、受かったから仕事がうまくいくとかはないです。
## 受かるために受ける？
受かるために受けてもまあ良い。
これらの知識を全て暗唱できる必要はなくて、雰囲気で内容がわかっていれば良いと思います。
「SSH通信とはこのような仕組みで、こういう場合に使用する」まで分からなくても、「SSH通信っていう、セキュアな通信プロトコルがある」ってのが分かっていれば（基本情報取るレベルとしては）十分。

※もちろんこれは弊社に限る話なので、どこでもそんな感じで行けるとは保証しかねます。
RMagickを導入して、既存の既存の画像ファイルを別のフォーマットに変換する

# 問題

すでにRMagickが導入されている環境において、既存の画像ファイルを別のフォーマットに変換したい場合は、どのようにすれば良いでしょうか? 

# 解決策

以下はローカルに存在するpngファイルをwebp形式に変換するサンプルコードになります。

```ruby
require 'rmagick'

image = Magick::ImageList.new('xxx.png')
image.write('xxx.webp')
```

# RMagickの導入

ここからはRMagickの導入方法を示します。

## ImageMagickの導入

RMagickは前提ソフトウェアとしてImageMagickを必要とします。インストール方法は環境ごとに[RMagickのREADME.md](https://github.com/rmagick/rmagick/blob/master/README.md)を参考にインストールしてください。わたしの環境はmacOSで、かつ、パッケージマネージャHomebrew導入済みなので、非常に簡単でした。

```
brew update
brew upgrade
brew install imagemagick
```

## RMagickの導入

Imagemagickの導入後はRubyGem経由で、rmagickをインストールします。これについても[RMagickのREADME.md](https://github.com/rmagick/rmagick/blob/master/README.md)が参考になります。ちなみにわたしは`bundler`を利用しました。

```
bundle init
vi Gemfile     #=> gem 'rmagick' を追記
bundle install
```

ちなみにRMagickの導入は結構トラブルが多いようなので、なにか困った場合は[RMagickのREADME.mdの"Things that can go wrong"](https://github.com/rmagick/rmagick/blob/master/README.md)を参考にするとよいと思います。

わたしの環境でも`bundle install`の際に以下のようなエラーが発生。

```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
ERROR: Can't install RMagick 4.1.2. Can't find pkg-config in
```

このトラブルについても"Things that can go wrong"の対応方法を元に解消することができました。

```
brew install pkg-config
```

# 環境情報

```
$ brew -v
Homebrew 2.5.1
Homebrew/homebrew-core (git revision a2bbe; last commit 2020-09-16)
Homebrew/homebrew-cask (git revision dfa88; last commit 2020-09-16)
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin18]
$ bundle -v
Bundler version 2.1.2
```
表側の条件で絞って集計する

# 表側の条件で絞って集計する
表側の条件で絞って集計する時に僕が使っている手法について紹介します。
宜しければ、使ってみてください！
（MYSQLで書きました）

例として、年齢階層ごとの表を作ります！

|年齢階層|患者数|
|:-:|:-:|
|51-55|1|
|56-60|5|
|61-65|3|
|66-70|1|

## 今回使うテーブル（PATIENT）

以下のサンプルテーブルのように、糖尿病にかかった人とその年齢区分を抽出する

```sql
CREATE TABLE PATIENT(
    ID INTEGER 
    ,AGE VARCHAR(4)
    ,DIS_NAME VARCHAR(30)
);

--DROP TABLE PATIENT;

INSERT INTO PATIENT VALUES (1, '62', 'Diabetes');
INSERT INTO PATIENT VALUES (2, '60', 'Diabetes');
INSERT INTO PATIENT VALUES (3, '56', 'Diabetes');
INSERT INTO PATIENT VALUES (4, '51', 'Diabetes');
INSERT INTO PATIENT VALUES (5, '57', 'Diabetes');
INSERT INTO PATIENT VALUES (6, '62', 'Diabetes');
INSERT INTO PATIENT VALUES (7, '60', 'Diabetes');
INSERT INTO PATIENT VALUES (8, '56', 'Diabetes');
INSERT INTO PATIENT VALUES (9, '68', 'Diabetes');
INSERT INTO PATIENT VALUES (10, '61', 'Diabetes');
```



|ID|AGE|DIS_NAME|
|:-:|:-:|:-:|
|1|62|Diabetes|
|2|60|Diabetes|
|3|56|Diabetes|
|4|51|Diabetes|
|5|57|Diabetes|
|6|62|Diabetes|
|7|60|Diabetes|
|8|56|Diabetes|
|9|68|Diabetes|
|10|61|Diabetes|

## 階級ごとにフラグを割り振ったテーブル（KBN）

51歳から70歳を5歳ごとに区切って集計する。

5歳ずつの階級の幅の条件として持たせたいため、その条件に当てはまるものを、AGE_KBNとして、フラグを作る。

```sql
CREATE TABLE KBN AS 
			
SELECT 
	AGE
	,DIS_NAME
	,MAX(CASE WHEN AGE BETWEEN 51 AND 55 THEN 1 ELSE 0 END) OVER (PARTITION BY ID) AS AGE_KBN1
	,MAX(CASE WHEN AGE BETWEEN 56 AND 60 THEN 1 ELSE 0 END) OVER (PARTITION BY ID) AS AGE_KBN2
	,MAX(CASE WHEN AGE BETWEEN 61 AND 65 THEN 1 ELSE 0 END) OVER (PARTITION BY ID) AS AGE_KBN3
	,MAX(CASE WHEN AGE BETWEEN 66 AND 70 THEN 1 ELSE 0 END) OVER (PARTITION BY ID) AS AGE_KBN4
FROM PATIENT
;
```
|AGE|DIS_NAME|AGE_KBN1|AGE_KBN2|AGE_KBN3|AGE_KBN4|
|:-:|:-:|:-:|:-:|:-:|:-:|
|62|Diabetes|0|0|1|0|
|60|Diabetes|0|1|0|0|
|56|Diabetes|0|1|0|0|
|51|Diabetes|1|0|0|0|
|57|Diabetes|0|1|0|0|
|62|Diabetes|0|0|1|0|
|60|Diabetes|0|1|0|0|
|56|Diabetes|0|1|0|0|
|68|Diabetes|0|0|0|1|
|61|Diabetes|0|0|1|0|


## 出力

今回用意したKBNテーブルと1~4の数字のテーブルであるIDXを使う。

WHEREで、IDXと自分が表側の条件として使いたいフラグを合わせる。

CASEでIDXの数字を、自分が使いたい表側の項目に書き換える。

```sql
SELECT 
    CASE 
        WHEN IDX = 1 THEN '51-55'
        WHEN IDX = 2 THEN '56-60'
        WHEN IDX = 3 THEN '61-65'
        WHEN IDX = 4 THEN '66-70'
    END AS "年齢階層"
	,COUNT(AGE) AS "患者数"
FROM
	KBN, (SELECT 1 AS IDX UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) I
WHERE
	(
	(IDX = 1 AND AGE_KBN1 = 1)
	OR (IDX = 2 AND AGE_KBN2 = 1)
	OR (IDX = 3 AND AGE_KBN3 = 1)
	OR (IDX = 4 AND AGE_KBN4 = 1)
	)
GROUP BY IDX
ORDER BY 1
;
```


|年齢階層|患者数|
|:-:|:-:|
|51-55|1|
|56-60|5|
|61-65|3|
|66-70|1|
pydanticでキーがCamelCaseのjsonをsnake_caseのクラスにキャストする

外部APIを使って実装するとき、REST APIの戻り値がCamelCaseなjsonであることもあります。例えば、PythonでAWSを`boto3`で操作するとき頻発します。

それではPythonのコーディング規約などを考えると少し困ったことになるのですが、[`pydantic`](https://pydantic-docs.helpmanual.io/)の[`alias_generator`という機能を使う](https://pydantic-docs.helpmanual.io/usage/model_config/#alias-generator)と簡単にsnake_caseをキーにした型にキャストできます。


ドキュメントでは`to_camel`という関数を自作していますが、私はAWSの操作で様々なクラスで利用するために外部ライブラリの[`inflection`](https://pypi.org/project/inflection/)を利用しています。

```python
from pydantic import BaseModel
from inflection import camelize


class Voice(BaseModel):
    name: str
    language_code: str

    class Config:
        alias_generator = camelize


voice = Voice(**{'Name': 'Filiz', 'LanguageCode': 'tr-TR'})
print(voice.language_code)
#> tr-TR
print(voice.dict(by_alias=True))
#> {'Name': 'Filiz', 'LanguageCode': 'tr-TR'}
```

# 参考

* [pydantic公式ドキュメント](https://pydantic-docs.helpmanual.io/usage/model_config/#alias-generator)
* [Elegant Python function to convert CamelCase to snake_case?](https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case)
nodebrewからnodenvへの変更、nodenv経由でyarnをインストール

# 概要
nodebrew, nodenvが環境に混在していたので、整理してnodenvに切り替えを行い、同時にnodenv経由でyarnをインストール出来るようにした備忘録


# 事前準備 nodebrewの削除

nodebrewをアンインストール

```
$ brew uninstall nodebrew
```

~/.bash_profile に書いてあるnodebreのPATHを消す

```
$ vi ~/.bash_profile

PATH=$HOME/.nodebrew/current/bin:$PATH #ここのPATHを消す
```

bash_profileを編集したら更新する

```
source ~/.bash_profile
```

node, yarn, npm、nodenvのversionを確認し、このように真っ白な状態になればok

```
$node -v
-bash: node: command not found
$yarn -v
-bash: yarn: command not found
$npm -v
-bash: npm: command not found
$nodenv -v
-bash: nodenv: command not found
```

nodeがまだ存在している場合
・ターミナルを再起動する
・pathの参照先を削除する

```
$ which node
/Users/[USER_NAME]/.nodebrew/current/bin/node
# 以下コマンドはディレクトリを間違えると全て消えてしまうので注意
$rm -rf /Users/[USER_NAME]/.nodebrew
```
またbrewlistでnodenv, node-buildが存在していたらアンインストールする

```
$ brew list
# nodenv, node-buildが存在する場合
$ brew uninstall nodenv
$ brew uninstall node-build
```


# nodenvのインストール

```
$brew install nodenv
$nodenv -v
nodenv 1.4.0
$which nodenv
/usr/local/bin/nodenv
$ nodenv init
```

~/.bash_profileに設定する

```
$ echo 'eval "$(nodenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

m1 macの場合

```
echo 'eval "$(nodenv init -)"' >> ~/.zshrc
source ~/.zshrc
```

以下で状況をチェックできる

```
$ curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
```
以下のようにokが表示されたらok

```
Checking for `nodenv' in PATH: /usr/local/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /usr/local/bin/nodenv-install (node-build 4.9.7)
Counting installed Node versions: 2 versions
Auditing installed plugins: OK
```


## nodenv-yarn-installの設定

nodenvがインストール出来たので、nodenv-yarn-installをインストールする

```
$ mkdir -p "$(nodenv root)/plugins"
$ git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install"
```

## nodeのインストール

準備が整ったのでインストールしたいnodeバージョンをインストールする

```
$ nodenv install 10.17.0
```


すでにインストールされているnodeはyarnがインストールされていないので、アンインストールし、再度インストールする

```
$ node -v
nodenv: node: command not found
The `node' command exists in these Node versions:
  10.15.3
  10.17.0
  12.10.0
$ nodenv uninstall 10.15.3
$ nodenv uninstall 12.10.0
$ nodenv install 10.15.3
$ nodenv install 12.7.0
```

グローバル（通常使用する方）を設定。


```
$ nodenv global 12.7.0
$ node -v
v12.7.0
```
yarnがインストールされていることも確認出来ました

```
$ yarn -v
1.22.5
$ which yarn
/Users/[username]/.nodenv/shims/yarn
```

## 補足
npm install globalしたあとはパスが通らないため下記を実行する

```
$ nodenv rehash
```

uninstallする場合はshimis以下を削除した方が残骸が残らない

```
$npm uninstall -g live-server
$which npm
/Users/{{username}}/.nodenv/shims/npm
$ls /Users/{{username}}/.nodenv/shims/
live-server     node            npm             npx             yarn            yarnpkg
$rm /Users/{{username}}/.nodenv/shims/live-server
```


# 参考記事
https://qiita.com/mame_daifuku/items/1dbdfbd4897b34df0d9f
https://qiita.com/ttokdev/items/3547587b0494dd624901
https://stackoverflow.com/questions/4608187/how-to-reload-bash-profile-from-the-command-line
https://qiita.com/awa2/items/1659347ce4109d9b4138#rehash
Cocoapodsのアンインストール方法


![uninstall.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722496/dca506f4-25d7-c086-16b0-354604c0ddd4.png)







（１）Macのコマンドを使って
自分が作成しているアプリのファイルの場所まで進む


（２）以下を入力してEnter
「gem list --local| grep cocoapods」

Cocoapodsのバージョンやファイルの一覧がでてきます。
（写真参照願います）


（３）cocoapodsのバージョンやファイル名が確認できたら以下を入力してEnter

sudo gem uninstall 「削除したいcocoapodsのファイル名」

僕の場合は８つのファイルをuninstallしました
（写真に赤線を引っぱっておきました）

以上です。

※「青」で塗りつぶしてあるところは
自分のmacの名前と　現在作成しているアプリのファイル名になります。
Amazon GameLiftに関する基礎知識

#概要
Amazon GameLiftについて調べる機会があったので、全体像を出来るだけ分かりやすいようにまとめてみた。

####参考にさせて頂いたサイト
Amazon GameLift の仕組み
https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/gamelift-howitworks.html#gamelift-howitworks-placing
Amazon GameLift – ゲームサーバー/クライアントのやり取り
https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/gamelift-sdk-server-api-interaction-vsd.html
AWS再入門ブログリレー Amazon GameLift 編
https://dev.classmethod.jp/articles/re-introduction-2020-amazon-gamelift/

#GameLiftとは？
> Amazon GameLift は、マルチプレイヤーゲーム用のクラウドサーバーをデプロイ、運用、スケーリングする、専用のゲームサーバーホスティングソリューションです。(公式サイトより転載)

GameLiftは簡単に言うと、マルチプレイに関する色々なことをいい感じに管理/運用してくれるすごいサービス。
主にマッチング、プレイヤー人数に合わせたサーバーのスケーリング、ログの収集などをやってくれる。
FlexMatchの仕組みを使えば、様々な条件を元に最適なマッチングをすることが可能で、待機時間により条件を段階的に緩和することも出来る。
例1:最初は遅延が少ないリージョンで対戦相手を探し、しばらく見つからなかった場合は遅延の上限を緩和して探す。
例2:最初はプレイヤーレベルが近い人を探し、しばらく見つからなかった場合はプレイヤーレベルの差の上限を緩和して探す。


#全体構成

ざっくりとしたイメージは以下の画像の通り。
![gamelift1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601695/9d795b3a-0b76-3e46-5eca-29fde3812de1.png)
クライアントからGameLiftにリクエストを送るフローに関しては、直接ClientSDKでGameLiftServiceに問い合わせる方法もあるが、今回の画像はAPI GatewayやLambdaを介しHttpリクエストで送る方法になっている。
このフローの方が、クライアントに直接リクエストの実装をするよりも安全で管理がしやすくなる。

#専用用語
画像の構成を理解する上で最低限必要な単語をまとめてみた。

## ・EC2

Amazon Elastic Compute Cloudの略
AWS上にスケーリング可能な仮想サーバーを構築出来るサービスのこと

## ・フリート

EC2インスタンス群形式のホスティングリソース
必要に応じて、インスタンス数を調節してくれる
![gamelift2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601695/47a08bc6-2e89-43ae-363f-167c8a71ae95.png)

## ・エイリアス

クライアントとフリートの中継地点
エイリアスに紐づけているフリートを変更することで、クライアントを変更せずに接続先のフリートを変更することが出来る
[https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/aliases-creating.html](https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/aliases-creating.html)

## ・キュー

新しいゲームセッションを作る場合に、複数のフリートから最適なものを選ぶ為の定義
リクエスト時にプレイヤーのpingを渡すと、最適なフリート(リージョン)を選んでくれる
ping情報が無い場合、キューに登録されているリストの順番で上から選ぶ
[https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/queues-design.html](https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/queues-design.html)

## ・マッチメイキングコンフィグレーション

マッチングする上での様々な設定をする
[https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/match-configuration.html](https://docs.aws.amazon.com/ja_jp/gamelift/latest/developerguide/match-configuration.html)

最低限必要な設定は以下の3つ

### ・ルールセット

GameLiftのダッシュボード->マッチメーキングルールセットから見れる
最大人数など、マッチングに関するルールが色々設定してある

### ・ゲームセッションキュー

紐付けるキュー

### ・リクエストのタイムアウト

タイムアウトの時間
それ以外にもいくつか設定出来る項目がある

### ・プレイヤーの承諾(no-acceptance-required)

マッチングに参加する場合に、承諾を要求するかどうか

### ・プレイヤースロットの予約(additional-player-count)

## ・API Gateway

クライアントからhttpリクエストを受け取る為のエンドポイント
Lambda(ラムダ)と紐付いていて、リクエストを受け取るとラムダの関数を実行してくれる

## ・Lambda(ラムダ)

GameLiftを操作する為の関数
APIGatewayなどをトリガーにして実行することが出来る
クライアントとGameLiftの繋ぎの役目で、クライアントに直接リクエストなどを実装するより安全で管理がしやすくなる


#まとめ
今回は全体構成のざっくりしたイメージと、最低限の単語にだけ触れてみた。
AWSは公式ドキュメントや利用者の記事が多く調べやすい反面、出来ることが膨大なので、全てを理解するのは大変そうだと感じた。
外部インスタンスからMySQLへの疎通を確認する。

外部インスタンスで下記コマンドを実行します。


```外部インスタンス
$ mysqladmin ping -h xxx.xxx.xxx.xxx --port 3306 -u username -p
Enter password:
```

MySQLのusernameのパスワードを入力してEnter。（3306はdefaultポートです）
`xxx.xxx.xxx.xxx`はMySQLインスタンスのIPです。


```外部インスタンス
mysqld is alive
```

疎通できているならこんな風になります。
Sequel ProでSSH Over Session Managerを使った踏み台サーバーのDBに接続する

# 結論
Sequel ProではユーザーのPATHを参照してくれないようなので、
brewなどでaws cliをインストールした場合、ssh_configでPATHを明示的に追加する必要があります

# ssh config を準備

```
Host AWSEC2
  HostName i-x0x0x0xx0x0x0
  User ec2-user
  IdentityFile ~/.ssh/id_ed25519
  ProxyCommand sh -c "PATH=$PATH:/usr/local/bin/ && aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
```

# Sequel Proに設定

SSHホスト名の欄にssh configのHostに設定した名前を入力します
SSHユーザ、SSH鍵などはssh configで設定してあるので、空欄のままで大丈夫です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100313/9f4d3717-96c5-dfb0-aa97-dc551083a3bf.png)

MySQLへの接続情報はshellでsshしたあとに叩くmysqlコマンドを確認して入力します

```
mysql -h <MySQLホスト> -u<ユーザ名> -p<パスワード> <データベース>
```
【Rails】rails dbコマンドまとめ


rails5.0からは、rakeコマンドとrailsコマンドどちらも使えるようになっている模様


#データベースを作成 / 削除する（定義元は、database.yml）

```
# 作成する
$ rails db:create

# 削除する
$ rails db:drop
```


#全てのテーブルをdropして、テーブルを再生成する

```
# db/schemaを元に再生成
$ rails db:reset

# db/migrateファイルを元に再生成
$ rails db:migrate:status
```


#マイグレーションファイルの一つ前の命令をなかったことにする

```
# 一つ前の命令をなかったことにする
$ rails db:rollback

# 二つ前までの命令を連続でなかったことにする
$ rails db:rollback STEP=2
```


#テストデータをデータベースに反映させる

```
# seedファイルを元に作成
$ rails db:seed
```



#開発環境の初期設定を一気に行う

```
# create / schema:load / seedコマンドを順に行う
$ rails db:setup
```


#参考記事

> https://qiita.com/parsetree/items/e9b08c6b11f762b949de
Rails:pluckを使う必要性

表記例

```
current_user.followings.pluck(:id)
#=>[1,2,3]

```

.plackは指定した引数の値をカラムから、配列で返してくれるメソッド

必要なデータだけを取れるのであればmapメソッドもあるが
何故pluckメソッドを使用するのか？

##理由
巨大なコレクションを操作する場合、
mapメソッドでは読み込んだ行を一行づつオブジェクトに変換しているが、使用するフィールドは全ては使用はしません。

必要なフィールドだけを読み込むことによって
・スピード
・メモリ使用量
の効率化が図ることができるようになる


##注意
pluckメソッドが返す値は配列を返してくれる

plackメソッド使用後、モデルの更新などを行いたい場合は使用することができないので注意が必要