OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS7でNFS関連通信の通信ポートを固定する

NFS関連サービスは一部ポート不定でサービスが動いてしまいます。
これではファイアウォールが存在する場合ポート番号が不定だと全てオープンする羽目になるので固定にします。

## 現状の確認
現時点で何番を使用しているか確認できます。

```shell-session:ポート番号例
# rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  55504  status
    100024    1   tcp  57693  status
    100005    1   udp  20048  mountd
    100005    1   tcp  20048  mountd
    100005    2   udp  20048  mountd
    100005    2   tcp  20048  mountd
    100005    3   udp  20048  mountd
    100005    3   tcp  20048  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  58737  nlockmgr
    100021    3   udp  58737  nlockmgr
    100021    4   udp  58737  nlockmgr
    100021    1   tcp  36949  nlockmgr
    100021    3   tcp  36949  nlockmgr
    100021    4   tcp  36949  nlockmgr
```

portmapperはTCP/UDP:111、nfs,nfs-aclはTCP/UDP:2049で固定ですが、status,mountd,nlockmgrは不定の模様です。

## 固定化
不定のポートを固定にします。なお、ポート番号はNFS設定のデフォルト値（？）を使用します。

```shell-session:
# cp -p /etc/sysconfig/nfs /etc/sysconfig/nfs.default
# vi /etc/sysconfig/nfs
# systemctl restart nfslock
# systemctl restart nfs
```

```shell:/etc/sysconfig/nfs※該当箇所のコメントアウトを外すだけ
# TCP port rpc.lockd should listen on.
LOCKD_TCPPORT=32803
# UDP port rpc.lockd should listen on.
LOCKD_UDPPORT=32769
# Port rpc.mountd should listen on.
MOUNTD_PORT=892
# Port rpc.statd should listen on.
STATD_PORT=662
# Outgoing port statd should used. The default is port
# is random
STATD_OUTGOING_PORT=2020
```

以上でポートが固定化されます。

* portmapper : TCP/UDP:111
* nfs,nfs-acl : TCP/UDP:2049
* status : TCP/UDP:662
* mountd : TCP/UDP:892
* nlockmgr : TCP:32803, UDP:32769

```shell-session:
# rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp    662  status
    100024    1   tcp    662  status
    100005    1   udp    892  mountd
    100005    1   tcp    892  mountd
    100005    2   udp    892  mountd
    100005    2   tcp    892  mountd
    100005    3   udp    892  mountd
    100005    3   tcp    892  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  32769  nlockmgr
    100021    3   udp  32769  nlockmgr
    100021    4   udp  32769  nlockmgr
    100021    1   tcp  32803  nlockmgr
    100021    3   tcp  32803  nlockmgr
    100021    4   tcp  32803  nlockmgr
```
【AWS】暗号化されたスナップショットからボリュームの再作成ができない

# 問題
暗号化されたボリュームのスナップショットからボリュームの再作成ができない。
リクエストは成功するけど、コンソール上に一向に表示されない。
暗号化されていないボリュームを、暗号化ボリュームとして再作成することはできてたのに。

# 原因
KMSポリシーにて、IAMユーザに`kms:ReEncrypt`がアタッチされていないことが原因でした。
CloudTrailのイベント履歴から`フィルター:イベント名:ReEncrypt`と検索してみると、当該リクエストが`エラーコード:AccessDenied`となっていました。

# 解決
IAMに`kms:ReEncrypt`がアタッチして、ボリューム作成するとすぐにコンソールにひょうじされました。暗号化(Encryp)と再暗号化(ReEncryp)で権限が区別されていることに注意が必要ですね。
【初学者向け】Route53でドメイン取得してポートフォリオに紐つける手順

# 前提条件
EC2でアプリをデプロイしている事
→もしまだデプロイ出来ていないのなら[こちら](https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1#nginx%E3%81%AE%E8%A8%AD%E5%AE%9A)の記事を参考にしてください。私も同じ様にやってきました。

# 手順
他にも沢山の参考記事がある為そちらを参考にしましたが、ドメイン取得に関しては[こちら](https://qiita.com/nakanishi03/items/25278fb4dfad60ebfac4)の記事で問題なく出来ます。
ただしこの記事にもある様にnginxで確実にエラーが出ます。
![nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431966/01253118-0605-16d3-e27e-754f63575a08.png)

なので、デプロイの時と同様に

```
[name(自分の名前)|~]$cd /etc/nginx/conf.d/

[name(自分の名前)|conf.d]$ sudo vi ◯◯.conf　#自分のアプリ名
 
```

```
# log directory
error_log  /var/www/rails/〇〇/log/nginx.error.log; #自分のアプリケーション名に変更
access_log /var/www/rails/〇〇/log/nginx.access.log; #自分のアプリケーション名に変更
# max body size
client_max_body_size 2G;
upstream app_server {
  # for UNIX domain socket setups
  server unix:/var/www/rails/mumu/tmp/sockets/.unicorn.sock fail_timeout=0; #自分のアプリケーション名に変更
}
server {
  listen 80;
  server_name ~~~.~~~.~~~.~~~;(#アプリのElastic IPに変更してください)←ここを取得したドメインに書き換えてください
  # nginx so increasing this is generally safe...
  keepalive_timeout 5;
  # path for static files
  root /var/www/rails/〇〇/public; #自分のアプリケーション名に変更
  # page cache loading
  try_files $uri/index.html $uri.html $uri @app;
  location @app {
    # HTTP headers
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }
  # Rails error pages
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /var/www/rails/〇〇/public; #自分のアプリケーション名に変更
  }
}
```
保存出来たらnginxを再起動します。

```
[name(自分の名前)|conf.d]$ cd /var/www/rails/〇〇　#自分のアプリ名
[name(自分の名前)|〇〇]$　sudo service nginx restart

Stopping nginx:                                            [  OK  ]
Starting nginx:                                            [  OK  ]
```
こうなっていれば大丈夫です！
後は取得したドメインを検索し問題なくサイトを開けるか確認してください！

# SSL化について
[【初学者向け】AWSでSSL化する方法](https://qiita.com/monsieur39/items/272be992f87ff2f81e7e)に記載しています。
【Effective Javaを読む】　第２章　項目５　『不必要なオブジェクトの生成を避ける』

#不必要なオブジェクトの生成を避ける

タイトルの通り。オブジェクトを不用意に生成しまくることはパフォーマンスの劣化につながる。
ちょっと工夫して無駄なオブジェクトを生成しない書き方をしましょうって話。

##用語集

###自動ボクシング
Javaではプリミティブ型(基本型)と参照型の2つの型がある。
プリミティブ型、例えばintをコレクションに置くことはできない。
コレクションはオブジェクト参照だけを保持できるため、プリミティブ値は適切なラッパークラス (int の場合はInteger) に「詰める (box)」必要がある。
オブジェクトをコレクションから取り出すときは、格納した Integer を取得します。int が必要な場合は、intValue メソッドを使用して、Integer から「取り出す (unbox)」必要がある。
これを明示的に実装することは煩雑さの原因であるため、自動ボクシング、アンボクシングの機能がJavaには存在する。
プリミティブ型→ラッパークラスの自動変換を自動ボクシング
ラッパークラス→プリミティブ型の自動変換をアンボクシングと呼ぶ。

|プリミティブ型|ラッパークラス
|---|---
| boolean | Boolean |
| char | Character |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |

###不変(immutable)

作成後にその状態を変えることのできないオブジェクトのこと。


##サンプルコード

このコードはこの箇所が実行されるたびに新しいStringインスタンスを生成してしまう。

```java:例１
String s = new String("stringette");  //これをやってはいけない
```

これならOK

```java:例２
String s = "stringette";  
```
その人がベビーブーム世代かどうかを判定するisBabyBoomerメソッドをもったPersonクラスを例に考えてみる。
↓の書き方だと、isBabyBoomerメソッドが呼ばれるたびに、不必要に新たなCalenderインスタンス、TimeZoneインスタンス、boomStart、boomEndのDateインスタンスを生成している。これはやってはいけない。

```java:例３
public class Person {
    private final Date birthDate;

    //他のフィールド、メソッド、コンストラクタは省略
    
    //これをやってはいけない！
    public boolean isBabyBoomer() {
        //コストの高いオブジェクトの不必要な生成
        Calender gmtCal = 
            Calender.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
        Date boomStart = gmtCal.getTime();
        gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
        Date boomEnd = gmtCal.getTime();
        return birthDate.compareTo(boomStart) >= 0 &&
               birthDate.compareTo(boomEnd)   <  0 ;     
    }
}

```
例３の悪いところを改善したのが例４。
クラスが初期化された時点で１度だけCalenderインスタンス、TimeZoneインスタンス、BoomStart、BoomEndのDateインスタンスを生成している。
これによってisBabyBoomerメソッドが頻繁に呼ばれるのであればかなりのパフォーマンス向上になります。

```java:例４
public class Person {
    private final Date birthDate;

    //他のフィールド、メソッド、コンストラクタは省略

    /**
     * ベビーブームの開始と終わりの日付。
     */
    private static final Date BOOM_START;
    private static final Date BOOM_END;

    static {
        Calender gmtCal =
            Calender.getInstance(TimeZone.getTimeZone("GMT");
        gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
        BoomStart = gmtCal.getTime();
        gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
        BoomEnd = gmtCal.getTime();
    }

    public boolean osBabyBoomer() {
        return birthDate.compareTo(BoomStart) >= 0 &&
               birthDate.compareTo(BoomEnd)   <  0 ;    
    }
}

```

例５は1文字の誤字のせいでかなり遅いです。
変数sumがlongではなくLongで宣言されています。
そのせいでプログラムは約2^31個の不必要なLongインスタンスを生成する。
（long i をLong sum に加算するごとに１つのインスタンスが増える）

`教訓：ボクシングされた基本データ型よりも基本データ型を選び、意図しない自動ボクシングに注意すること`


```java:例５
//恐ろしく遅いプログラム！　オブジェクト生成を指摘できますか？
public static void main(String[] args) {
    Long sum = OL;
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    System.out.println(sum);
}

```

#続く
【Effective Javaを読む】　第２章　項目６　『廃れたオブジェクト参照を取り除く』
https://qiita.com/Natsukii/items/5f2edd6a9bcdb94b03e5
【IE対応】Google Material Iconsをdata 属性を使ってスマートに表示する

## Google Material IconsをIE対応して使うには？


### 方法1： HTMLで直接書く

```html
<i class="material-icons">email</i>
```
一番簡単な方法ですが、問題が1つあります。
グーグルの検索結果に表示されるようなタイトルやメニュー部分にこの方法でアイコンを設置してしまうと、`emailお問い合わせフォーム`のような形でアイコンのコードが
テキストとして一緒に表示されてしまいます。

### 方法2： CSSで旧文字コードを使って書く
Google Material IconsをCSSで表示することができます。
[公式サイト](https://material.io/resources/icons)の「email」などのコードを`content`に入れることで使えますが、IEでは
以前の文字コードじゃないと表示されません。。

``` scss
.material-icon::before {
   font-family: Material Icons, sans-serif;
   content: "\e0be"; //IE以外は「email」でOK
}
```

ただ、この方法だとアイコン毎にCSSを書かなければいけないためかなり面倒です。

## HTMLだけで擬似要素として表示させる
CSSで表示できれば何も問題ないので、`<i class="material-icons">email</i>`のようにHTMLで完結した上で、擬似要素として表示する方法をまとめました。

## ベースのHTML・CSSを用意

``` scss
.material-icon::before {
   font-family: Material Icons, sans-serif;
   content: attr(data-icon);
}
```
``` html
<i class="material-icon" data-icon="文字コード"></i>
```
`data-icon`に入れたコードが`content:`にはいるようになります。
ベースができたので、アイコンを表示するために以下の手順で文字コードを用意します。

## 1. 使いたいアイコンを選ぶ
今回は[公式サイト](https://material.io/resources/icons)から「email」を選びます


## 2. 文字コードを調べる
「email」で検索して「e0be」の文字コードを取得
[文字コード一覧：GitHub](https://yamatonamiki.com/blog/196/)
<img width="450" alt="スクリーンショット 2020-07-31 10.27.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457046/92a9ae8e-2539-b92b-8f5b-9c28766d7f16.png">

## 3. 10進数に変換する
`data-icon="\e0be"`で表示されて欲しいところですが、これだと表示されません。
「\」を「&#」にした上で、e0beを10進数にすることで表示されます。

[変換ツール](https://hogehoge.tk/tool/number.html) 
<img width="529" alt="スクリーンショット 2020-07-31 10.29.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457046/07050a02-8adf-a137-cc6c-8bd9b3c2d491.png">


## できた
``` html
<i class="material-icon" data-icon="&#57534;"></i>お問い合わせ
```
<img width="138" alt="スクリーンショット 2020-07-31 11.24.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457046/21d7ac1f-445c-b154-a506-4dd26f551e52.png">
これで検索結果のテキスト表示も無く、アイコンの追加はHTMLだけでできるようになりました。文字コードを探して変換する手間はありますが、CSSで毎回設定するよりは楽になります。
標準出力の文字に色をつける方法

# 端末のフォント・背景の色変更について

CSI（制御コード）で端末などの標準出力に色をつけることができる。
シェルスクリプトの他、どのプログラミング言語でも標準出力に制御コードを出力すれば良い。

制御文字を標準出力に出力してしまうと、ファイルにリダイレクトしたときにファイルに制御文字が入り込んでテキストエディタで読めなくなる。

簡易的な解決策としては、制御文字を標準エラー出力に、表示したい文字を標準出力に出力しておけばよい。
これで標準出力をリダイレクトしない場合は画面に色付きで文字が表示され、標準出力をファイルにリダイレクトした場合は、通常の文字だけがファイルに出力されるようになる。（標準エラー出力に制御文字が出力されているが、文字自体を表示しないので、何も起きない）

ただし、標準エラー出力もファイルにリダイレクトするとそのファイルには制御文字が含まれてしまうのであくまでも簡易的な方法。

# サンプル

```bash
#!/bin/bash

if [ $# -lt 4 ]; then
  echo "Usage: $0 <text> <R> <G> <B>"
  echo "  color values: 0-255"
  exit 1
fi

text=$1
R=$2
G=$3
B=$4
bR=$((255 - $R))
bG=$((255 - $G))
bB=$((255 - $B))

# フォントの色変更
echo -ne "\033[38;2;${R};${G};${B}m" >&2

# 背景色変更
echo -ne "\033[48;2;${bR};${bG};${bB}m" >&2

# 文字を標準出力に出力
echo $text

# CSIリセット
echo -ne "\033[0m" >&2
```
resourcesとresourceを組み合わせて使う時の注意点についてまとめてみた

先日、resourcesとresourceの違いについてまとめてみましたが、組み合わせて使う際の注意点もあったのでまとめてみました。
違いについてはこちら → [resourcesとresourceの違い - Qiita](https://qiita.com/oga_4528/items/34383126264ca0263338)

## resourcesとresourceを組み合わせて使う場合
resourcesとresourceを組み合わせて使うと、下記のようなルーティングが簡単に生成できます。

- 全ユーザーの一覧表示
- 全ユーザーの詳細表示
- 自ユーザーの詳細表示
- 自ユーザー情報の編集

全ユーザー一覧、各ユーザーの詳細については、誰でも表示できるが、ユーザー情報の編集は自分のものしかできないという状態。

```:config/routes.rb
  resources :users, only: [:index, :show]
  resource :user, only: [:show, :edit, :update]
```

`rails routes`で生成されたルートを確認すると、下記のような感じ。

```:ターミナル
   Prefix Verb  URI Pattern          Controller#Action
    users GET   /users(.:format)     users#index
     user GET   /users/:id(.:format) users#show
edit_user GET   /user/edit(.:format) users#edit
          GET   /user(.:format)      users#show
          PATCH /user(.:format)      users#update
          PUT   /user(.:format)      users#update
```

`user GET   /users/:id(.:format)  users#show`の部分、user_pathが/users/:idに割り当てられてしまうことで、/userを返すべきヘルパーメソッドが生成されない。
ということで、順番を逆にして記載してみた。


```:config/routes.rb
  resource :user, only: [:show, :edit, :update]
  resources :users, only: [:index, :show]
```

`rails routes`で生成されたルートを確認すると、下記のような感じ。

```:ターミナル
   Prefix Verb  URI Pattern          Controller#Action
edit_user GET   /user/edit(.:format) users#edit
     user GET   /user(.:format)      users#show
          PATCH /user(.:format)      users#update
          PUT   /user(.:format)      users#update
    users GET   /users(.:format)     users#index
          GET   /users/:id(.:format) users#show
```

自ユーザーは、ログイン機能（session管理）で特定できれば、リクエストに:idを含む必要はないので、自ユーザーに関するルーティングは`resource`を使用しています。

自分以外のユーザーの詳細画面を見るには、対象となるユーザーのIDを指定する必要があるので、`resources`でリクエストに:idを含むルートを生成しています。

## 結論
単数形で使用する`resource`と、複数形で使用する`resources`を組み合わせてルーティングを作る際は、単数形の`resource`を上に書くようにする。
lsやfindの「*」は正規表現じゃないの？

**正規表現** と **ワイルドカード** の区別がついていませんでした。

以下の例題は、『Linux教科書 LinuCレベル1 Version 10.0対応』の模擬試験より。

## 例題

以下のディレクトリで`ls file[123]*3*`を実行したとき、表示結果はどうなるか。

```bash
$ ls
file3
file3.txt
file313
file33
file33.txt
```

## 誤答のプロセス

`file[123]*3*`ということは、

* fileが含まれる
* つぎに、**「１，２，３」のどれかが0個以上含まれる**
* つぎに、**「3」が0個以上含まれる**

だから、

* file3 -> 一致する
* file3.txt -> 一致する
* file313 -> 一致する
* file33 -> 一致する
* file33.txt -> 一致する

「なんだ、ひっかけ問題か。全部正解ね」と答えていました。

## 正答

しかし実際の答えは、

```bash
$ ls file[123]*3*
file313
file33
file33.txt
```

であり、「file3」、「file3.txt」は一致しません。

## 理由

`file[123]*3*`を**正規表現だと判断したこと**が誤りでした。

具体的には、`ls`コマンドや`find`コマンドでは正規表現は利用できません。

では上の場合のアスタリスクは何なのか。それが「ワイルドカード」です。

## ワイルドカード

このアスタリスク（ワイルドカード）は、**それ単体で「任意の文字列」を表します。**

> ワイルドカードでは「任意の複数文字に一致」ですが、正規表現では「直前の文字を0回以上繰り返したものに一致」です。
https://www.atmarkit.co.jp/ait/articles/0112/04/news003_2.html より

つまり`file[123]*3*`は、

* fileから始まる **（このエントリでは省略しますが、正規表現ではないので「含まれる」でなく「始まる」が正解）**
* つぎに「1,2,3」のどれかが入る
* 任意の文字列がある
* 「3」が含まれる
* 任意の文字列がある

と読み解くのが正解です。よって、

* file3 -> 「1,2,3」のどれかが入ったあと、「3」が含まれない
* file3.txt -> 「1,2,3」のどれかが入ったあと、「3」が含まれない
* file313 -> 「1,2,3」のどれかが入ったあと、任意の文字列があり、「3」が入る
* file33 -> 「1,2,3」のどれかが入ったあと、任意の文字列（０文字）があり、「3」が入る
* file33.txt -> 「1,2,3」のどれかが入ったあと、任意の文字列（０文字）があり、「3」が入り、任意の文字列がある

となり、正答の通りであることを確認できました。

## ちなみに

この参考書（初版）にはいくつか誤字・脱字があったので、「なんだ、これも誤ってるじゃないか」と思って調べたのが学習のキッカケでした。

人を疑う前に自身を疑うべき、というのも教訓のひとつでした。

さらにそういえば、ファイル検索するときは`find test*.txt`みたいに検索していました。試験勉強のせいか、「お、これは正規表現を問う種類のやつだな」と深読み（？）していたのも誤答の原因です。

似たような疑問を持った方が読んで納得してくれれば！
【Python】BeautifulSoupでタグを指定して削除

最近、Pythonでスクレイピングをしていて、いらないタグを指定して削除したいな〜〜〜〜と思ったらあったのでメモ

### BeautifulSoupインストール

BeautifulSoupを使用するのでBeautifulSoup4をインストールします。

```
$ pip install beautifulsoup4
```

### サンプル



```py3
from bs4 import BeautifulSoup

>>> marks  = '<p><span class="category">Information</span><span class="bdy"><a href="https://www.sample.com/">Now <br>available!</a></span></p>'
>>> soup = BeautifulSoup(marks, 'html.parser')
>>> a_tag = soup.find("a")
>>> print(a_tag)
>>> br_tag = soup.find("a")
>>> br_tag.decompose()
>>> print(a_tag)

# 出力結果
# <a href="https://www.sample.com/">Now <br/>available!</a>
# <None></None>
```

参考
https://www.whyit.work/entry/2019/04/04/101538
https://qiita.com/mtskhs/items/edf7dbba9b0b0246ef8f
【Bootstrap4】d-flexも使おう、row / colだけがレスポンシブを表現するわけじゃない

Bootstrap4を利用していたときの気づきをご紹介します。

# こういうデザインにしたいときがある

```
PC版
[ あなたのお名前：marshmallow88             ▶変更する ]

SP版
[  あなたのお名前：           ]
[  marshmallow88            ]
[                  ▶変更する ]
```

仕様の確認をしてしましょう。
上記は以下の要素に分かれています。

- あなたのお名前
- 名前
- 変更する

そして仕様は以下のようになります。

1. PC版では、`あなたのお名前` + `名前` が左寄せ、`変更する`は右寄せ
2. SP版では、`あなたのお名前`、`名前`、`変更する`がともに改行され、かつ`変更する`は右寄せ 

# Bootstrap4を利用して、row + col を利用して書いてみると...？

cssがそこまで得意ではないので、やはりよく頼るのがCSSフレームワーク、Bootstrapはその代表格です。
ではBootstrapを使って、row + colのクラスを利用して書いてみましょう。仕様どおりに作成できるでしょうか...？

```html
<div class="row">
    <div class="col-md text-danger">
        あなたのお名前：
    </div>
    <div class="col-md font-weight-bold">
        marshmallow88
    </div>
    <div class="col-md text-right">
        ▶変更する
    </div>
</div>
```

まず仕様2に関して満たせるようになります。`col-md`を指定しているので、SP版の場合はブレイクポイントの範囲外となるため、flex-basisやflex-growなどのスタイルが付与されないため、それぞれブロックが積み上がる状態で表示がされます。

では次に仕様1についてはどうでしょうか。実はここで問題が発生します。`col-**` 関係はそれぞれ両端にpaddingを取るため、`[あなたのお名前:＿名前]`のような空白が発生しています。ではどうするのか。

# d-flex + flex-column + flex-md-row を利用して表現する

`d-flex`は知っていて、なるほど`display:flex;`にする程度のものだと思っていたのですが、それ以外にも`flex-column`や`flex-md-row`を併記することで、仕様を実現することができます。

```html
<div class="d-flex flex-column flex-md-row">
    <div class="text-danger">
        あなたのお名前：
    </div>
    <div class="font-weight-bold">
        marshmallow88
    </div>
    <div class="flex-md-fill">
        ▶変更する
    </div>
</div>
```

`flex-column` はflex-directionをcolumnに、つまり縦方向に並べます。そして、`flex-md-row`はmdのブレイクポイントの対象となる場合に、flex-directionをrowにします。つまり普通のflexによる横並びが実現されます。

上から順に、

- display: flex; に変更
- flex-direction: column; に変更
- mdのブレイクポイントの対象となる場合は、flex-direction: row;に変更（※メディアクエリで指定されています）

という仕組みでレスポンシブを実現しています。

# flexだけ知っているだけじゃなく、flex-directionも知ろう

flexは雰囲気で書いていたけれど、原理の解説記事を起こすと、改めてflexのことを知らないのだなあと思いました。特定のサイズのみに対応するのであれば横並べのためにflexを使い、縦並びにはdivで積む、といったことで対応できます。ですが、様々なデバイスサイズに対応したものを作成するとなったときに、やはりflex-directionの知識も知っておくとよいなと思いました。
「ログインできない！」と言われた話

前に[セッションの記事](https://qiita.com/Ohtak/items/8f9352cee7787ee0cef5)を書きましたが、それに関わる話
こういうこともあるんですね、という共有です

#経緯
先週まで普通に動いてた管理画面にて、「ログインできないんですけど…」という作業者からの問い合わせがありました。
環境は

- cakephp2.4.10
- nginx
- php-fpm


#現象

- cakephp2のAuthで構築したログイン画面にIDとパスを入れる
- その直後ログイン画面にリダイレクトされる
- 以降繰り返しでTOPに入れない

#先に結論
原因はセッションファイルを読み込めていないことでした。
ログイン状態を記憶できてなかったのでこんな不思議現象が。。

下記は対応記録です。

#対応記録

##まずはログを確認
何も出てない。ということはつまりエラーではない。
急に発生したということでサーバーの環境が変わった方を疑いました。
ちなみにログ出力先の設定はデフォルトなのも確認しました。

##ログイン処理が成功してるかどうか確認

```php
public function login() {
		$this->log("認証処理開始", LOG_DEBUG);
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				$this->log("ログイン成功", LOG_DEBUG);
				$this->redirect($this->Auth->redirect());
			} else {
				$this->log("ログイン失敗", LOG_DEBUG);
				$this->Session->setFlash(__('Invalid username or password, try again'));
			}
		}
	}
```

こんなログを仕込んでみたところ、ちゃんと「成功」のログが。
ということでここまでは正常のようです。
（ついでにログの出力先も予想通りなので、やっぱりエラーは出てないようです。）

ログイン成功してるけどまたログインに飛ばされる、ということはもしかしてログイン状態が記憶されてない？
Authではそれをセッションで管理しているため、保存できてるか確認します。

##セッションを保存できてるか確認
https://qiita.com/kazu56/items/a54596e963d9e2b71f2e
セッション保存できてるかどうかは`$this->Auth->user()`を見ればいいようです。
AppControllerの先頭にログを仕込むと

```
2020-07-27 11:27:42 Debug: セッション保存のユーザー :
```

ということで空文字が出力されてます。やっぱり保存されてないっぽい
自分で適当に`$Session['test']`を定義してみても同様

##設定確認
https://inoccu.com/blog/2012/11/21/223145.html
cakephpでセッションをデフォルトで使うとファイルで管理されます。
ということで、このファイルにアクセスできてない説が濃厚。
core.phpの設定は

```php

Configure::write('Session', array(
		'defaults' => 'php',
		'timeout' => 60,
	));
```

クックブック見ると「phpの設定に準拠」とのことなのでphp.iniを確認

```
session.save_path => no value => no value
```

なんだって…orz
デフォルトのパスにもない…orz

##保存パスを探して三千里
https://qiita.com/cranpun/items/02eaa615c523aac8f375
設定ファイルで上書きされてる可能性があるとのこと。
問題の環境はnginxですがphp-fpmも使ってるので上書きされてる可能性はありそう。
ただし設定ファイルはめちゃくちゃな数があり、探せど探せど見つからないので諦めました。
（どうせ今の設定だとアクセスできてないし）

##cakeの設定を変えればいいじゃない

```php

Configure::write('Session', array(
		'defaults' => 'php',
		'timeout' => 60,
	));
```

を

```php

Configure::write('Session', array(
		'defaults' => 'cake',
		'timeout' => 60,
	));
```

に変えました。これで`APP/tmp/session`に保存されるようになります。
sessionフォルダを作って権限設定して解決！と思いきやまだダメでした。

##cookie削除しなきゃダメですよ
セッションの同一性はcookieで判断されます。
よってダメだった時のcookieが残ってるとうまくいきません。
ということでブラウザのCookieを削除して確認するとやっと正常に動いてくれました。

##原因推測

- 使ってるサーバーはNFSを使ってソースコードの共有をしていた
- そのノリでセッションファイルも共有していたのでは？という推測。
- そしてそこにアクセスできなくなったのが大元の原因では？という推測

古いシステムのため設定を知ってる人もいない＋ドキュメントにも書いてないので迷宮入り…
仮に共有されてたとしても、このサーバーはELBを噛ませてるわけでもないので問題ないと判断しました。

#教訓

- ログイン系に異常があったらセッション周りも疑う
- php.iniの設定は上書きされてることもある。
- **<font color="red">普通と違う設定使ってるならドキュメントを書きましょう（ブチギレ）</font>**
Rails 本番環境で画像が読み込まれないエラー


##この記事について
本番環境でbackground-imageの画像を読み込む時にはエラーが出ないのに、image_tagのところだけでエラーが出てしまっていたので、そのエラー解決方法について

##環境
・Ruby 2.6.6, Rails 6.0.3.2
・Docker,Docker-compose（開発環境）
・AWS/本番環境（EC2, RDS, VPC, EIP, Route53, IAM, S3）



##参考URL
https://stackoverflow.com/questions/49440304/rails-asset-is-not-present-in-asset-pipeline-when-using-image-tag
この人と全く同じ現象になってました。


##出ていたエラー
```ruby:qiita.rb
ActionView::Template::Error (The asset "chat_example.jpeg" is not present in the asset pipeline.):
```
asset へのパイプラインがうまくいっていない様子



##解決方法

config/environments/production.rbにある、config.assets.compile = falseをtrueに変えてあげる。

```ruby:config/environments/production.rb
- config.assets.compile = false
+ config.assets.compile = true
```
NUXTのサブコンポーネント内で非同期データを扱うと描画がめちゃ遅くなる

描画がめちゃおそになったのでメモ。

NUXTの子コンポーネント内で非同期データを扱うには2通りの方法があるそうな。

https://ja.nuxtjs.org/faq/async-data-components/


>mounted() フック内に API コールを作成し、ロード時に data プロパティをセットすること。マイナスな側面: サーバーサイドレンダリングでは機能しません

この方法を試してみたところ、データを取得してからDOMの描画が行われるためか、描画がめちゃ遅くなる。
generateでもデータ読み込むとこだけ遅れて描画される。

参考
https://www.kimullaa.com/entry/2019/12/01/132724

```
<template>
  <ul>
    <template v-for="item in result">
      <template v-if="item.sectionsKey === 1">
        <li>
          <div><nuxt-link :to="item.url">{{ item.pages }}</nuxt-link></div>
          </div>
        </li>
      </template>
    </template>
  </ul>
</template>

<script>
import axios from "axios"
export default {
  data(){
    return{
      result: ''
    }
  },
  created() {
    this.asyncData()
  },
  methods: {
    asyncData() {
      axios.get('https://script.google.com/macros/s/id/exec')
      .then((res) => {
        this.result = res.data
      })
    }
  }
}
</script>
```

#2つめの方法の方がいい

>ページコンポーネントの asyncData() または fetch() メソッド内に API コールを作成し、データを props としてサブコンポーネントへ渡すこと。この方法ではサーバーサイドレンダリングでもうまく機能します。マイナスな側面: ページ内 asyncData() または fetch() が他のコンポーネントのデータをロードするため、可読性が落ちるかもしれません。

これもSSRだといちいち通信が走るので描画が遅くなるけど、generateすると関係ないので、generate前提であればこれでいいかも。

```oya.vue
<template>
  <directive :jsonData="result">
</template>

<script>
import axios from "axios"

export default {
async asyncData({ $axios }) {
    //jsonデータを取得
    const url = 'https://script.google.com/macros/s/id/exec';
    const response = await $axios.$get(url);
    return { result: response }
  }
}
</script>
```

```ko.vue
<template>
  <!-- 整形はいい感じに -->
  {{ jsonData }}
</template>
<script>
export default {
  props:['jsonData']
}
</script>
inline、block、inline-block達

ちょっと忘れてたのでメモ
###inline
横並びになるよ
縦横(width,height)は無視されるよ
中央揃えには親要素にtext-alineをつけるよ
###block
改行されるよ
縦横が反映されるよ
中央揃えにはmarginで左右をauto指定するよ(widthの値が設定されている必要がある)
###inline-block
横並びになるよ
縦横が反映されるよ
中央揃えには親要素にtext-alineをつけるよ
条件付き確率をベン図を使って覚える

## はじめに
E資格対策のため、応用数学を勉強していたのですが、「条件付き確率」がなかなか覚えられませんでした。（どちらがAかBか分からなくなる)
ベン図を使って視覚的に理解すると忘れにくそうなので、理解過程をメモしておきます。

## 条件付き確率の公式
事象Aが起こる条件で、事象Bが起こる確率は、次のような式になります。
$$ P(B|A) = \frac{P(A \cap B)}{P(A)} $$

事象Bが起こる条件で、事象Aが起こる確率は、次のような式になります。
$$ P(A|B) = \frac{P(A \cap B)}{P(B)} $$

AとBが入り乱れて、数式で覚えられませんでした。

## ベン図で理解する

全事象をU、各事象をA,Bとしたベン図です。
![ベン図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/e5010d69-8fce-8591-a3a4-2965342f10f0.png)

### 事象Aの確率

![事象A](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/63d809bd-f64a-bac5-934b-f996dd823f9b.png)

事象Aの確率 $ P(A)$ は、$ 事象A \div 全事象U $ なので、

$$ P(A) = \frac{A}{U} $$

となります。



### 事象Aと事象Bの積集合の確率

![積集合](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/0522f457-162d-f6c7-e5e6-2f5fa73e7231.png)

積集合の確率 $ P(A\cap B)$ は、$ 積集合 \div 全事象U $ なので、

$$ P(A\cap B) = \frac{A\cap B}{U} $$

となります。

### 条件付き確率

![条件付き確率](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385793/35f813b9-5576-d7d4-f14d-dfb4c9c6c373.png)

条件付き確率 $ P(B|A)$ は、事象Aの範囲内で事象Bが起こった確率なので、$ 積集合 \div 事象A $ となります。


$$ P(B|A) = \frac{A \cap B}{A} $$

右辺の分母と分子に全事象Uを割れば、条件付き確率の公式になります。

$$ P(B|A) = \frac{ \frac{A \cap B}{U}}{ \frac{A}{U}} $$

$$ P(B|A) = \frac{P(A \cap B)}{P(A)} $$



## 参考

下記の動画を参考にしました。
[数学Ａ基礎講座「条件付き確率とベイズの定理」](https://www.youtube.com/watch?v=LTmxXVrNgQU&t=60s)
アドレスバーで検索しようと文字入力するとMicroSoft Edgeが落ちる【解決】

2020/7/31のアップデートで、アドレスバーで文字検索しようとすると落ちる様になった。

調べたところ既に問題は解決してパッチも配信されている様なのに、こちらのブラウザが更新されなかったため少しハマってしまったので覚書。

メニュー→ヘルプとフィードバック→Microsoft Edgeについてを開くと最新に更新され、不具合は解消されました。
Vueでパスワード確認用入力欄のバリデーションをしようと思ったけどそもそもパスワード確認はオワコンだった

# これはなに

オワコンは言い過ぎかもしれません。
パスワード確認用入力欄はいらないのかもしれないというメモです。

# パスワード確認用入力欄とは？ 


パスワード確認用入力欄とは、以下のようなフォームのことを指してます。


![スクリーンショット 2020-07-31 10.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/8caa777f-f895-2001-0938-ac61e9746f68.png)


ユーザーの登録フォームなどにあって、
パスワードを2回入力することでパスワードの入力ミスを防ぐための入力欄です。

# 経緯

今回、弊社プロダクトのユーザーの登録フォームをNuxtに置き換えることになり、VeeValidateというバリデーションパッケージを使ってパスワードの入力確認のバリデーションを実装する必要が出ました。

そこで、参考のために他サイトでの「パスワード確認用入力欄」の動きを見てみたのですが、Facebook、Yahoo、Qiita、Green,Teratailなどのサイトを見ても「パスワード確認用入力欄」が見つかりません。
（Appleはパスワード確認用入力欄がありました）

自分の普段のウェブ利用について考えると、他サイトを登録した時にパスワードを間違って登録したとしても、
すぐにパスワード再発行することで対応していることに気づきました。

もしかして、「パスワード確認用入力欄」はいらないのでは？

# パスワード確認用入力欄はいるか？

パスワード確認用入力欄は、パスワードの入力ミスを気づかせ、間違ったパスワードでユーザー登録してしまうのを防ぐものです。
間違ったパスワードでユーザー登録してしまうと、パスワードの再発行をしなければなりません。
パスワードの再発行は手間ですよね。
その点では、パスワード確認用入力欄は、ユーザーの手間を減らすことができているといえるでしょう。

しかし、以下の問題があります。

- パスワードを2回打ち間違えると意味がない
- パスワードを2回打たなければならない 
- パスワード不一致でパスワードを再度入力しなくてはいけない（どこで間違ったかわからないため）
- 入力欄が1つ多くなるので、入力欄の数の多さを見て離脱してしまう確率があがる

あまりユーザーの手間を減らせているとは思えません。
登録フォームのUXがよくなければ、そこで離脱されてしまいます。

他に、ユーザーの手間を減らす方法はあるでしょうか？

最近よく目にするのが、パスワード入力欄のマスクON/OFF機能です。
マスクをオフにすることで、自身が入力した文字列がなんなのかがわかります。

マスクOFF機能は、パスワード確認用入力欄と比較して以下のメリットがあります。

- 入力ミスに気づくことができる
- 2回入力しなくていい
- 入力欄が1つ減る

マスクOFF機能があれば、パスワード確認用入力欄と同じく、パスワードの入力ミスに気づくことができます。
入力欄がすっきりすれば、登録フォームでの離脱率も下がるはずです。

ABテストなどの検証をしたわけではないので、実際にユーザーにいいUXだと感じてもらえるかはわかりません。

個人的には、マスクOFFが好きです。
私は、パスワードがわからなくなったらパスワードの再発行をすればいいというタイプなので、
入力が一回で済むならそちらのほうがいいです。


# まとめ

パスワード確認用入力欄は別にいらないんじゃないかという話でした。


# 参考
https://uxmilk.jp/18568
https://f-tra.com/ja/blog/column/4567
https://note.com/sadako_a_/n/n9abe75dce8ba
https://appleid.apple.com/account#!&page=create
[rails]Controller作成と同時にアクションとviewファイルを作成

#Controller作成と同時にアクションとviewファイルを作成
railsではcontrollerを作成する際、同時にアクションとviewファイルを作成することができます。
実際に手動でアクションやviewファイルを作成する手間を省くことができます。
以下がコマンドの型です。

```
$ rails g controller コントローラ名 アクション名
```

例えば、book controllerを作成し、newアクションを追加したい場合、、、

```
$ rails g controller book new
```

こんな感じになれば、成功。

```
[vagrant@localhost sample_app]$ rails g controller books new
Running via Spring preloader in process 25819
      create  app/controllers/books_controller.rb
       route  get 'books/new'
      invoke  erb
      create    app/views/books
      create    app/views/books/new.html.erb
      invoke  test_unit
      create    test/controllers/books_controller_test.rb
      invoke  helper
      create    app/helpers/books_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/books.coffee
      invoke    scss
      create      app/assets/stylesheets/books.scss
```
VSCODE Remote DevelopmentでBad owner or permissionsが発生した場合の対処


**やりたかった事**
Windows10からWindows10にSSH接続してVSCODEでリモート開発を行いたい。
接続先にはOpenSSHサーバーをインストールしており、PowerShellで「ssh ユーザー名@192.168.X.X」で接続が成功している。
しかしVSCODEの拡張機能(Remote Development)を使用してSSH接続しようとした際に以下のエラーが発生！

**エラー内容**
Bad owner or permissions on C:/Users/ユーザー名/.ssh/config

**対処法**
1. VSCODEで設定を開く
2. 「Remote」と検索
3. Remote.SSH: Config File項目の欄にconfigファイルのフルパスを記入
![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535228/49687627-cf69-ec2b-72de-5e2f12af6927.png)

バックスラッシュを2つ入れるのがミソらしい


参考資料
[Bad Owner or Permissions on username\.ssh\config file #3210](https://github.com/microsoft/vscode-docs/issues/3210)
[rails]カラムの追加と削除

#カラムとは？
カラムとはデータベースの中のテーブルが持つ要素です。
例えば、ユーザーというテーブルの中の「名前、生年月日、住所」などの項目をカラムと言います。

#カラムの追加
新たに別のカラムを追加したいということはよくあると思います。
そんなときは以下のコマンドでカラムを追加です。

```
$ rails g migration Addカラム名Toテーブル名 カラム名:型名
```

例えば、「User」というテーブルに「name」というカラムを追加したい場合、

```
$ rails g migration AddNameToUsers name:string
$ rails db:migrate
```

ここで「rails db:migrate」を忘れてしまうと、テーブルへ反映されませんので、
気をつけてください。

#カラムの削除
カラム名を間違えて登録した時など、カラムを削除したいこともあると思います。
カラムを追加する時とあまり変わりません。

```
$ rails g migration Removeカラム名Fromテーブル名 カラム名:型名
```

「User」というテーブルの「name」というカラムを削除したい場合、

```
$ rails g migration RemoveNameFromUsers name:string
$ rails db:migrate
```

ここでも「rails db:migrate」は忘れずに。
PHP 「?:」 の正体を知ってすっきりした話

# 目的

- 先輩方が開発に携わったLaravelアプリのソースコードをみていたら自分の知らない処理が出てきて驚いた話をまとめる

# 初見のコード

- 自分が初めて見たコードを下記に記載する。

    ```php
    変数 = 比較対象A === 比較対象B ?文字列1:文字列2;
    ```

# 簡単な解説

- 処理内容を下記に簡単に記載する。
    1. 比較対象Aと比較対象Bを比較する。
    1. データ型も含めて比較し、一致しているのかしていないのかを確認する。
    1. 一致していた(true)の場合、文字列1が変数に格納される。
    1. 一致していない(false)の場合、文字列2が変数に格納される。
- この`?`と`:`を用いた記載(`?:`)は条件演算子と呼ばれる物である。
- 下記に処理を記載する。

    ```php
    条件式 ?式1:式2;
    ```
- 上記の様な処理の場合、条件式が真(true)の時に式1を実行し、偽(false)の時に式2を実行する。

# 具体例

- 下記の様なコードを実行した時の結果を考える。

    ```terminal
    $a = 'staging';
    $b = 'dev';

    echo $a === $b ? 'OK' : 'NO';
    ```
- 上記を実行すると「NO」と出力される。
- 下記の様なコードを実行した時の結果を考える。

    ```terminal
    $a = 'dev';
    $b = 'dev';

    echo $a === $b ? 'OK' : 'NO';
    ```
- 上記を実行すると「OK」と出力される。
アンチウィルスソフトの動作検証で使用する検体（サンプル）を探せ！

エンタメ系企業の社内もろもろを担当しているakibinです。

#アンチウィルスソフトの動作検証をしたい
と思い、動作検証で使用できる検体を探してみました。

#探索
###【EICARテストファイル】
その名の通り、EICARが提供しているテストファイル。特定の文字列をメモ帳などにコピペして拡張子（.com）を付けて保存するだけ。
詳しくは[EICARテストファイル](https://ja.m.wikipedia.org/wiki/EICAR%E3%83%86%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)を参照ください。

###【Microsoftテスト用マルウェア】
[MicrosoftDfenderATPのページ](https://demo.wd.microsoft.com/page/BAFS)でMicrosoftアカウントでログイン、その後［Create & download new file!］からダウンロード可能です。
ただ、chromeでダウンロードしようとするとその時点でウィルス判定で✕をくらいダウンロードできないので、他のブラウザでやってみましょう。いいぞいいぞGoogleさん！

####【他には...】
ただいま探索中です！発見しましたら更新します！

#補足：セキュリティベンダーさんに聞いたはなし
[VirusTotal](https://www.virustotal.com/gui/home/upload)というファイルやウェブサイトのマルウェア検査を行う海外のウェブサイトへ有償登録、またセキュリティベンダーである証明ができれば、本物のマルウェア（ランサムウェアなど）を入手できるようです。本物なので扱い要注意…

テスト検体を使用して、アンチウィルスソフトの性能を比較しまくりましょう！！
Filemaker Server 17 on Windows Server(オフライン)  のライセンス更新手順

業務でFilemaker Server 17のライセンス更新を行ったため、手順を残しておきます。

ドキュメントおよびカスタマーサポート・技術サポートに問い合わせた内容に基づいて記載していますが、情報の正確性を保証するものではありません。
参考: [FileMaker Server のライセンスを、評価版からフルバージョンに更新する](https://support.claris.com/s/article/FileMaker-Server-%E3%81%AE%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E3%82%92-%E8%A9%95%E4%BE%A1%E7%89%88%E3%81%8B%E3%82%89%E3%83%95%E3%83%AB%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AB%E6%9B%B4%E6%96%B0%E3%81%99%E3%82%8B-1503692952128?language=ja
)

# TL;DR

* Filemaker Serverをオフライン環境下で利用している場合、ライセンス証明書をインポートして有効期限を更新する
* 更新前と注文したライセンスの構成（商品種類・数量）が変更されている場合、現在の有効期限が切れるまでライセンスが更新されているか分からない


# 1. ライセンスの発注

クラリスのカスタマーサポート経由でライセンスを発注します。
（もしかしたら省略できるかも知れませんが）注文書の捺印・スキャンや、クレジットカード番号を伝えるための電話が必要なのでオフィスで作業した方がいいかもしれません。

注文完了後、以下のようなメールが届きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/15f37c5b-1d09-8d60-4e58-5293f501e661.png)

# 2. ライセンス証明書の保存

注文完了のメール内のリンクからライセンス証明書を保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/3c234991-183e-ef87-606a-b83506e43bcd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/555d2ef2-613c-0a0f-869d-67309540cf2c.png)

# 3. ライセンスの更新

Filemaker Serverのコンソールを開きます。
http://localhost:16001/admin-console/app/dashboard

`ライセンス証明書のインポート` を選択して実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/910a40e6-c902-ba1d-6879-333e6cbba315.png)

インポートされたファイルは `C:\Program Files\FileMaker\FileMaker Server\CStore\LicenseFile\LicenseCert.fmcert` にコピーされているようです。
（パスは環境によって異なるかもしれません）

# 4. Filemaker Serverの再起動
サービスを開き、「サービスの再起動」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/e4ee6599-9535-7758-0df4-9d89e8389321.png)

# 5. （ライセンスの構成が前回注文から変更されている場合）有効期限切れを待ちます。

有効期限が切れるのを待ちます。
ここまでの手順でライセンス証明書が正しくインポートされていれば、現在の有効期限が切れた際に新しいライセンスが有効になるそうです。

もしも上手くいかなかったらそのときにサポートに問い合わせましょう。

以上です。
elasticsearch-php で全件取得

elasticsearch-php で特定のindexから全件取得する方法です。


### 方法１
index だけを指定すると全件取得になるようです。
sort 設定をしたいので body に入れています。


```php
use Elasticsearch\ClientBuilder;

class ElasticSearch
{
    public function getAll()
    {
        $client = ClientBuilder::create()
            ->setHosts([ENV('ELASTICSEARCH_HOST', 'elasticsearch') . ':' . ENV('ELASTICSEARCH_PORT', '9200')])
            ->build();

        $searchResults = $client->search([
            'index' => 'index_name',
            'body' => [
                'sort' => [
                    'created_at' => ['order' => 'desc'],
                ],
            ],
        ]);
    }
}
```


### 方法2
最初こちらの方法２しか知らなかったので方法1を使わなかったのですが、特に理由がなければ方法1で良さそうでした。
動作に微妙な違いがあるかもしれませんが、詳細は未検証です。

match_all を使うと全件取得になります。

```php

use Elasticsearch\ClientBuilder;

class ElasticSearch
{
    public function getAll()
    {
        $client = ClientBuilder::create()
            ->setHosts([ENV('ELASTICSEARCH_HOST', 'elasticsearch') . ':' . ENV('ELASTICSEARCH_PORT', '9200')])
            ->build();

        $searchResults = $client->search([
            'index' => 'index_name',
            'from' => 0,
            // 設定可能上限値なので実質無制限扱い
            'size' => 10000,
            'body' => [
                'query' => [
                    // see: see: https://github.com/elastic/elasticsearch-php/issues/495
                    'match_all' => (object)[]
                ],
            ],
        ]);
    }
}
```
G検定に合格しました

先日、G検定を受験し、合格しました！
その記録を残しておきます。

※記事にするのがだいぶ遅れましたが、受験したのは7月4日です。

※データサイエンス・インフラに関わる検定試験としては4つ目です。

- [AWS Certified Big Data - Specialty 2019年10月](https://qiita.com/suzuki-navi/items/8b2fe5a35a4439013461)
- [AWS Certified Machine Learning – Specialty 2019年11月](https://qiita.com/suzuki-navi/items/3664bfbc102052717426)
- [統計検定2級 2020年5月](https://qiita.com/suzuki-navi/items/e353b8dfbc6e872f9f41)
- G検定 2020年7月

G検定は日本ディープラーニング協会が開催している機械学習・ディープラーニングの基礎知識を問う検定試験です。

SNSでのみんなの反応をみると、いままでよりも難易度が上がったように感じた人が多かったようです。

一方で合格率があまり変わっていないので合格のハードルが大きく下がっているかもしれません。

私は初めての受験で、事前に問題集もあまりこなせていなかったので、傾向の変化はよくわかりません。

合格の価値はよくわかりませんが、ひと通り幅広く勉強する機会を作れたことはよかったと思っています。

試験中は自由にPCもネットも使えるので、問題をメモして、あとで復習・自己採点しました。G検定の試験を通して一番勉強したのは試験の後の復習のときだったかもしれません。


# 勉強方法

私の勉強方法を書いておきます。

## 1. 公式テキストを読む

試験の1週間ぐらい前からこの本を読み始めました。

[深層学習教科書 ディープラーニング G検定(ジェネラリスト) 公式テキスト](https://www.amazon.co.jp/dp/4798157554/)

試験前日の夕方の時点で半分ぐらいしか読んでなくて、前夜以降に残りを進めました。

ノートも取り、試験中に参照できるように整理しました。試験後にブログにノートを貼りました。以下のブログ記事は試験後の復習で追記したキーワードも含みます。

- [人工知能の一般知識](https://suzuki-navi.hatenablog.com/entry/2020/07/05/053853)
- [機械学習の一般知識](https://suzuki-navi.hatenablog.com/entry/2020/07/06/234025)
- [ディープラーニングの基本](https://suzuki-navi.hatenablog.com/entry/2020/07/09/205317)
- [ディープラーニングの応用](https://suzuki-navi.hatenablog.com/entry/2020/07/10/234240)
- [産業への応用](https://suzuki-navi.hatenablog.com/entry/2020/07/17/215140)


## 2. YouTubeにある非公式の模擬試験の解説を見て雰囲気を感じる

YouTubeに動画を上げているチャンネルがいくつかあります。例えばこれです。

[JDLA G検定模試をひたすら解説する！ - YouTube](https://www.youtube.com/watch?v=9_5NqeW6gc4)

これを見て、わからないところがあったら調べてノートに書き足します。

試験前の数日の間で少しずつ見ました。


# 試験

自宅で自分のPCで受験します。自分のノートはいつでも参照できますし、ググれます。

ノートに関しては、試験中に実際に参照したことはほとんどありませんでした。ノートを書くことで覚えられたものが多かったのかもしれません。

わからないキーワードが出てきたらググるのですが、2時間で200問、1問あたり30秒あまりなので、そもそも理解していない内容はちょっとググったぐらいですぐに確証を持って正解にたどり着けるとは限らず、ググれるからといって簡単なわけではなかったです。

時間に余裕がなかったのですが、残り時間を計算しながら問題を進めて、残り数分のところで最後まで到達しました。途中自宅のネットワークが何度か切れてしまって、ログインし直す自体になったときは焦りました。

試験後のSNSの反応を見ていると、公式テキストに載っていない法律や時事問題が多い、という感想も多かったのですが、私はそんなに多いとは感じなかったです。

自己採点では200問中、誤答または怪しいという問題は15問でした。自己採点が合っていれば正答率9割超です。


# 合格発表

試験は7月4日(土)で、13日(月)〜17日(金)の間に発表とされていて、16日(木)14時に発表のメールが来ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490207/af2c402a-0292-186d-011a-a476314d0c24.png)
BootstrapでjQueryが使えなかった話

####使用環境
- Rails5.2.4
- Bootstrap3

## 背景
Railsにて、Bootstrap使用時になぜかナビゲーションバーのハンバーガーのトグルが作動しない。yarnでjQueryは入れたし、jsのマニフェストファイルにもjQueryを読み込むように書き込み済み。

## マニフェストファイルを確認してみる。
とりあえず読み込みがうまくいってないのでマニフェストファイルを確認してみる。

```app/assets/javascripts/application.js
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require bootstrap/dist/js/bootstrap.min
//= require jquery/dist/jquery.js
//= require_tree .
```
下から2行目でちゃんとtreeの上に書いてるし問題なさそうなのに、なんでだあ？
## マニフェストファイルは順番が大事みたい
結論としてjQueryを読み込む順番を変えたら解決した。

```app/assets/javascripts/application.js
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require jquery/dist/jquery.js //入れ替えた
//= require bootstrap/dist/js/bootstrap.min
//= require_tree .
```
Bootstrapを読み込む前にjQueryを読み込ませないとだめみたい。
Railsだとcssファイルの読み込みも順番が結構重要なので意外と繊細だなあって感じ
IntelliJ + Kotlin覚書

# 概要

IntelliJとKotlinについて

# リンク

* [10分で環境構築！IntelliJ IDEAとJDKをインストール (Windows)](https://pouhon.net/kotlin-start/897/)
* [IntelliJでKotlin REPLを実行する方法](https://pouhon.net/kotlin-repl/974/)
【Go】依存性注入ライブラリwireの使い方【DI】


# Hello, World

## DI とは
[Weblio辞書から引用](https://www.weblio.jp/content/Di?edc=BINIT#:~:text=DI%E3%81%A8%E3%81%AF%E3%80%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B,%E6%A6%82%E5%BF%B5%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82&text=%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%88%90%E7%AB%8B%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE,%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%A8%E3%81%95%E3%82%8C%E3%82%8B)
*DIとは、プログラミングにおけるデザインパターン（設計思想）の一種で、オブジェクトを成立させるために必要となるコードを実行時に注入（Inject）してゆくという概念のこと*

現在Go言語で[クリーンアーキテクチャ](https://qiita.com/nrslib/items/a5f902c4defc83bd46b8)を使用して開発をしているのですが、、依存関係のメソッドを呼び出すのにwireを利用したのでメモしておきます。

## wireの使い方

```:ターミナル
go get github.com/google/wire/cmd/wire
```

プロジェクトにdiディレクトリを作成し、その中にwire.goを作成して以下を記述します。

```go:wire.go
// +build wireinject

package di

func InitReview() handler.Review {
	wire.Build(
         db.New,
         repository.NewReview,
         usecase.NewReview,
         handler.NewReview,
	)
	return nil //明示的にnilを返す
}
```

このwire.Buildのカッコ内に依存関係を解決するメソッドを全て(順不同)入れます。
クリーンアーキテクチャを採用している場合だと例えばrepositoryはDBの値を実際に操作するパッケージ(一番外側のinfra層になる)としていますが、これをusecaseで呼び出すときに外側のinfra層からは呼び出せないので、usecase層よりも内側で空のインターフェースの中の関数を呼び出しています。その依存関係を解決して実際のinfraの関数をdiを使って呼び出しています。

このコードをもとに、実際に使うメソッドを生成するコマンドを打ちます。

```:ターミナル
wire ./di/wire.go
```


```go:wire_gen.go
func InitReview() handler.Review {
	conn := db.New()
	review := repository.NewReview(conn)
	usecaseReview := usecase.NewReview(review)
	handlerReview := handler.NewReview(usecaseReview)
	return handlerReview
```

こんな感じの関数が生成されたら成功です。あとは実際にこの関数をhandlerで呼び出してあげれば全て使用することができます。お疲れ様でした。


すごくざっくり書いたので質問や訂正あればコメントお願いします。以上です。
【PhpStorm】ファイルのすべての関数にPHPDocを生成する

### コマンド

Alt + Insert でGenerate ウィンドウを開き、一番下のPHPDoc Blocksを選択
<img width="191" alt="generate.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109300/996cd6c7-e231-93cc-5cdf-066c6c6ea84b.png">

PHPDocを生成したい関数を指定して、OKを押すと自動でPHPDocを生成してくれる

### 補足
Generate ウィンドウは他にgetter setterやコンストラクタも生成してくれるので便利
GAS の権限に関わるエラーの一種

よくわからない GAS の内部エラーをひとまず解決したのでメモだけ。調査しきらないまま解決してしまったので、推測を含みます。


## 要約
Chrome としてログインしているアカウントと、スプレッドシート・GAS 上でログインしているアカウントが異なる場合がある。スプレッドシートと GAS だけで完結する操作なら問題は発生しないが、`modaldialog` や `sidebar` のように HTML 要素が絡んでくるとそれが効いてきて、権限の処理に引っかかり、エラーが出ることがある。


## 詳細
Google スプレッドシートにデータチェック機能を持たせるために、GAS で処理を書いて、スプレッドシートの上部メニューから実行できるようにしていた。データ整形の段階に応じていくつかスクリプトを用意していたが、同一スクリプトでも、ある環境からは正しく実行されるのに、ある環境では実行されない現象が発生した。

以下は Chrome のデベロッパーツールが吐いたエラーログだが、`Uncaught` とだけ表示されていて原因が分からない。こちらが書いた GAS スクリプト上でエラーが起きているのなら、ログに該当関数やその行数、エラーの詳細（`undefined` なり `invalid` なり）が表示されるはずであるが、それも無い。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526487/05a1447f-af9d-b73f-78e8-0fd76320aa17.png)

エラーの発生個所から察するに、GAS の内部処理に関する js ファイル上で何らかのエラーが起きているらしいが、難読化されているので全く見当がつかない。


### HtmlService を呼び出す関数でのみエラー
複数用意した処理のうち、スプレッドシートと GAS の間でデータをやりとりするだけの単純な処理ではエラーが発生しなかった。一方、`sidebar` や `modaldialog` のような `HtmlService` を介する処理、たとえばまず設定用ダイアログを表示して、そこで処理の細かい設定を行なってから、改めてスプレッドシートに処理を行なうようなものについては、エラーが発生した。


### 特定の Chrome でのみエラー
複数の環境から実行してみたところ、そのうち１つの環境の Chrome で、とあるアカウントに切り替えたときのみエラーが出た。環境間の違いを調べてみたところ、このアカウントでは特殊なログイン状況が発生していることが分かった。

Chrome にはユーザー管理システムがあり、google アカウントを登録しておけば、右上のユーザーメニューから簡単にログインアカウントを切り替えることができる。

ところが当該 Chrome では、デフォルトの「ユーザー１」のままいったん組織の GSuite アカウント `A` でログインしたのち、ログアウトし、スプレッドシートには別の無料アカウント `B` でログインするなどした結果、妙な Cookie の残りかたをしてしまったようで、「Chrome としては `A` でのログイン履歴があるが、現在スプレッドシートには `B` でログインしている」ような状況になっていた。

従って、スプレッドシートと GAS の間でデータの処理が完結するようなスクリプトでは問題なかったが、`sidebar` や `modaldialog` のような HTML を同一画面内に表示し、そこから（HTML 内のスクリプトから）GAS の関数を呼び出そうとした結果、アカウント `A` からアカウント `B` の GAS にアクセスするような事態が発生し、権限周りでエラーが起きていたのではないかと考えられる。


### 解決策
Google およびアカウント `A` に紐づいた組織サイトの **Cookie をすべて削除し**、あらためてログインしなおすことで環境を正常化することができた。しばらく試したが、同様の状況はそれ以降再現しなかったのが残念。

スクリプト作成にあたって `.gs` のほうにはいくらか `try-catch` を仕込んだりしていたが、HTML のほうは非常にシンプルな処理だったので、エラーハンドリングを怠ってしまった。これが一番の敗因かもしれない。
文字エンコーディングの違い


## 文字集合(CCS)と文字符号化方式(CES)
文字コードには、`文字集合は同じでも符号化方式が違う文字コード`がある


`文字集合` JIS X 0208
`符号化方式` JISコードやEUC-JP

- 日本語の文字集合
    - JIS X 0208
        - JISコード
        - EUC-JP
        - Shift_JIS
- 世界中の全ての文字を共通の文字集合/符号化方式
    - Unicode
        - UTF-8
        - UTF-16


- `文字集合が同じ` 場合、符号化方式が違っても`容易に変換が可能`
- 符号化方式が同じでも、`文字集合が違う場合変換が難しい`
    - EUC-JP(日本語)
    - EUC-KR(韓国語)
    - EUC-CN(中国語)

## 文字エンコーディング

### ASCII
- `英語などラテン文字`を中心とした文字コード
- 1文字を7ビット(=0~127)で表現
    - 残り1ビットは通信エラーチェック用のパリティビットになる

### JISコード (ISO-2022-JP)
- `日本語`を中心とした文字コード
- 日本語を利用する`電子メール`の多くで採用されている
- ASCIIと同じく7ビットで表現
    - 残り1ビットは、漢字モードであることを示す文字列になっている

### Shift_JIS
- `日本語`を中心とした文字コードでよく使う
- `CSV`などで利用されている
- 漢字は2バイトで表現するが、ASCIIコードと被る領域があり、`文字化けする可能性`がある

### EUC-JP
- `日本語`のUnix/Linuxで長らく使われてきた
- ASCIIが利用していない上位ビットを使うことで文字種類を判別

### Unicode
- `文字集合と符号化方式を定めた規格`
- UTF-16
    - 16ビットで符号化したもの
    - Windowsなどの`OS内部`で利用されている
- UTF-8
    - 可変長1-4バイトの8ビットで符号化したもの
    - Webの`HTML5`で標準の文字エンコーディング
GitとGitHubの関係性について

#はじめに#
**Gitとは**
ソースコードのバージョンを管理するツール
**GitHubとは**
Gitを利用した、開発者を支援するWebサービス

GitとGitHubですが、関連性は強ものの別物であり、Gitを利用しているからと言ってGitHubを使用しなければならないというわけではありません。
後述しますが、GitのホスティングサービスはGitHub以外にも存在しております。


##Git誕生の歴史と利便性##
そもそもGitはどのようにして誕生したのか。
その経緯から、Gitの利便性を確認していきましょう。

Gitの生みの親はLinuxOSを作った**リーナス・トーバルズ氏**です。
氏は、当初Linuxカーネル開発で「BitKeeper」というバージョン管理システムを用いておりました。
ライセンスの問題により「BitKeeper」使用することができなくなったため、代替するサービスを探したもののフリーのバージョン管理システムでは、氏の掲げる高度な要求水準を満たせるものはありませんでした。
そのためトーバルズ氏自ら開発に着手し、そこで誕生したものが「**Git**」になります。
ではこれまでのバージョン管理ツールと比べてGitは何に優れているのでしょうか。

Gitが優れている点、それは**分散型のリポジトリ**であることにあります。
従来リポジトリは全体で1つでしたが、Gitは「ローカル」と「リモート」の2つを持っています。
この分散型のメリットは、システム開発を複数で行った場合に、開発者それぞれがソースコードを書いていきリポジトリに追加していくことになるため、開発者が増えればその分だけ**リポジトリに不整合が生じる**可能性が高まります。

そういったリポジトリの不整合を防ぐために、各開発者が自身のマシンで**ローカルリポジトリ**に変更を記録していき、全体の状況を見て**リモートリポジトリ**に変更を記録していくことで利便性が高まりました。

分散型という今までにない形でバージョン管理を行うことで、従来の管理ツールに対して感じていた懸念は払拭され、現在に至るまで開発に用いられるようになりました。

##GitHubとは##
Gitという言葉がついているので、専用サービスのような印象を受けますが、こういったGitのホスティングサービスとしては他にもあり、GitHubを必ず利用しなければならないというわけではありません。

GitHubは、クラウド上でGitを用いたバージョン管理をすることができ、Gitを更に使いやすくする機能が備わっております。
その中でも**「フォーク」「プルリクエスト」「マージ」**の3つの機能があることで、利便性が向上し、多くのユーザーから支持を得ています。

- フォーク:誰かのリポジトリを取得（コピー）して改変することができる。
- プルリクエスト:自身が行ったソースコードの変更点について他のメンバーにレビュー依頼ができる機能
- マージ:人のコードを自分のコードに導入すること。

---
「フォーク」してコードの改修を行い、オーナーへ「プルリクエスト」を行う。
「プルリクエスト」を受けたオーナーはそのコードを「マージ」する。

---

また、GitHubはソーシャルコーディングの場とも呼ばれており、他の人のソースコードを見ることができます。
これによって、開発への参加やフィードバックなどオープンソースでの開発がしやすくなったのもGitHubのメリットになります。

###GitHub以外に使用されている代表的なGitのホスティングサービス###

- [Bitbucket](https://bitbucket.org/)
- [GitLab](https://about.gitlab.com/)
- [CloudForge](https://www.cloudforge.com/)
- [tracpath](https://tracpath.com/)

各種選ばれる違いとしては、ホスティングがWebサービス型とインストール型で違うことや、対応するVCSの違い、無料のプライベートリポジトリ、料金形態と様々です。

##まとめ##
Gitとは分散型にする事で、開発効率をあげる目的を持ったバージョン管理ツールであり、
GitHubはそれをオープンソースとしてチーム開発の利便性向上や、技術者のコミュニティ形成に役立っているサービスである。

##参照記事##
ITmedia エンタープライズ
https://www.itmedia.co.jp/enterprise/articles/0504/20/news075.html
FERROWS
https://job.fellow-s.co.jp/useful_info/feature_detail/Art-0488
Linix.com
https://www.linux.com/
【Rails】エラー解決 Unsupported argument type: 1 (Integer)

###はじめに

今回は
`Unsupported argument type: 1 (Integer)`
こんなこと言われた時の対処方を記述します
お決まりのタイプミスによって発見したエラー文です笑

###解決策

***intger型の１という引数は期待してません***、という感じのエラー文です。

という事は違う物を期待してるところで整数の１を渡してしまっているという事です。

```rb
User.find_by(session[:user_id])
```
犯人はこれでした！

`find`と書くべきところを間違えて`find_by`と書いてますね、なので`find_by`のカラム名を書くところに`session[:user_id]`が入っているせいで、今回は[１]という整数が入ってるのでそのまんま[1]って名前のカラムを探しに行こうとしてしまった、そんな感じみたいですね。

>↓こんな感じの事ですね！

>```rb
>User.find_by(1)
>```


という事で

```rb
User.find(session[:user_id])
```
`find`に書き換えて解決！

###学び
- `find`を`find_by`と間違えると高確率で`Unsupported argument type: ... (Integer)`が出ると思うのでこんな感じのエラーを見かけたら`find`周りチェックするのがいいかもですね！
PHP: CouchDB のデータを削除 (Delete)

```php:couch_delete.php
#! /usr/bin/php
<?php
// ------------------------------------------------------------------
//	couch_delete.php
//
//						Jul/31/2020
//
// ------------------------------------------------------------------
include('Requests/library/Requests.php');

fputs (STDERR,"*** 開始 ***\n");
$key_in = $argv[1];
print	"key_in = " . $key_in . "\n";

Requests::register_autoloader();

$url_base = 'http://localhost:5984/nagano';
$url_target = $url_base . "/" . $key_in;

$request = Requests::get($url_target, array('Accept' => 'application/json'));

// var_dump($request->status_code);

$json_string = $request->body;
$data_aa = json_decode ($json_string,true);

// var_dump($data_aa);

if (array_key_exists ("_rev",$data_aa))
	{
	print($data_aa["_rev"] . "\n");
	print($data_aa["name"] . "\n");

	$url_del=$url_target . "?rev=" . $data_aa["_rev"];

	$result = Requests::delete($url_del);

	// var_dump($result);
	}
else
	{
	fputs (STDERR,"*** key doesn't exist ***\n");
	}

fputs (STDERR,"*** 終了 ***\n");

// ------------------------------------------------------------------
```

実行

```bash
./couch_delete.php t2024
```
PHP: CouchDB のデータを更新 (Update)

```php:couch_update.php
#! /usr/bin/php
<?php
// ------------------------------------------------------------------
//	couch_update.php
//
//						Jul/31/2020
//
// ------------------------------------------------------------------
include('Requests/library/Requests.php');

fputs (STDERR,"*** 開始 ***\n");
$key_in = $argv[1];
$population_in = $argv[2];

print	"key_in = " . $key_in . "\n";
print	$population_in . "\n";

Requests::register_autoloader();

$url_base = 'http://localhost:5984/nagano';
$url_target = $url_base . "/" . $key_in;

$request = Requests::get($url_target, array('Accept' => 'application/json'));

// var_dump($request->status_code);

$json_string = $request->body;
$data_aa = json_decode ($json_string,true);

// var_dump($data_aa);

if (array_key_exists ("_rev",$data_aa))
	{
	print($data_aa["_rev"] . "\n");
	print($data_aa["name"] . "\n");

	$url_up=$url_target . "?rev=" . $data_aa["_rev"];

	date_default_timezone_set('Asia/Tokyo');
	$today = date ("Y-m-d");

	$unit_aa = array();
	$unit_aa["name"] = $data_aa["name"];
	$unit_aa["population"] = $population_in;
	$unit_aa["date_mod"] = $today;
	$str_json = json_encode ($unit_aa);

	print $str_json . "\n";
	$headers = array('Content-Type' => 'application/json');
	$result = Requests::put($url_up,$headers,$str_json);

//	var_dump($result);
	}
else
	{
	fputs (STDERR,"*** key doesn't exist ***\n");
	}

fputs (STDERR,"*** 終了 ***\n");

// ------------------------------------------------------------------
```

実行

```bash
./couch_update.php t2022 5923400
```
【Laravel】マイグレーションとシーディング

こちらの記事は以下の書籍を参考にアウトプットとして執筆しました。
[PHPフレームワークLaravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AFLaravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798060992/ref=tmm_hrd_title_0?_encoding=UTF8&qid=1595991312&sr=1-2)

#マイグレーションとは
今使っているDBと同じ構造のDBを再現する仕組み

DBのバージョン管理機能があり、DB移行や新規作成がPHPスクリプトでできる。

##マイグレーションの手順
専用スクリプトを作り、スクリプトを書き、実行する
###マイグレーションファイル作成
```
php artisan make:migration ファイル名
```
>出典[PHPフレームワークLaravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AFLaravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798060992/ref=tmm_hrd_title_0?_encoding=UTF8&qid=1595991312&sr=1-2)

##作成されたファイルの中身について

テーブルを作成する処理を書くupメソッドと、
テーブル削除する処理を書くdownメソッドの2つのメソッドがテーブル操作の基本

###テーブル生成
####タイムスタンプの設定
この書籍では`$talbe->timestamp()`を実行するとcreated_atとupdated_atが作成されると述べています。

##テーブル削除
###テーブルを削除(テーブルがない場合はエラー)
```
Schema::drop(テーブル名)
```

###テーブルを削除(テーブルがあれば削除)
```
Schema::dropIfExists(テーブル名)
```

##マイグレーションの実行コマンド
```
php artisan migrate
```
これで`database/migrations`野中のファイルが実行される。
#シーディング
マイグレーションでテーブルを作成してとき、最初にレコードを登録する
この機能をシーディング機能という

以下コマンドでシーダーファイルを作成する

```
php artisan make:seeder シーダーファイル名
```

このあとrunメソッドにレコードを作成するコードを書く

そしたらシーダーファイルが実行されるようにDatabaseSeederに登録する

このDatabaseSeederがシーダコマンドで実行される。