OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】データベースにサンプルデータを作成する方法【seeds.rbの設定】

# データベースにサンプルデータを作成する方法

`db/seeds.rb`にサンプルデータを書く

```db/seeds.rb
User.create!(name:  "Example User",
             email: "abc@example.com",
             password:              "foobar",
             password_confirmation: "foobar",
             admin: true)
```

データベースをリセットして、サンプルデータを生成する

```
$ rails db:migrate:reset //databaseを一度削除してもう一度作成し、db:migrate実行
$ rails db:seed //seeds.rbに沿ってデータを生成
```

## おまけ：複数のデータを一度に大量作成する方法

複数のデータをいっぺんに作成したい場合は、`100.times`のように回数を指定してサンプルデータを生成することもできます。以下、その流れです。

```db/seeds.rb
100.times do |n|
  name  = "example-#{n+1}"
  email = "example-#{n+1}@example.com"
  password = "password"
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password)
end
```

データベースをリセットして、サンプルデータを生成する

```
$ rails db:migrate:reset
$ rails db:seed
```

`rails dbconsole`でデータベースを確認すると、サンプルデータが生成されています。

以上です。


参考文献：[Ruby on Rails チュートリアル 10章](https://railstutorial.jp/chapters/updating_and_deleting_users?version=5.1#cha-updating_showing_and_deleting_users)
Windowsの新しいターミナルソフト「Windows Terminal」を使ってみた

Windowsの新しいターミナルソフト`Windows Terminal`のプレビュー版が公開されていたので、使ってみました。
特徴としては下記ですかね。

* オープンソース
* タブ管理
* GPUを利用したテキストレンダリングで高速
* カスタマイズ機能

WSL(Windows Subsystem for Linux)や、VSCodeなどようやくWindowsでも開発環境が整ってきた感じがします。

# Windows Terminalのインストール
インストールはMicrosoft Storeから入手する形になります。
無料なので、入手を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/751ef562-0c85-35f9-c105-6422713e7fa4.png" width="600">

# Windows Terminalを使う
インストールが完了したら起動してみます。
![wt002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/41cfa6c2-196f-5b5e-7782-9e1acdee6930.png)
このとおり、プログラムに追加されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/5bce397e-d080-3109-c220-ce2792bef45f.png" width="800">
起動すると、こんな感じ。
最初はタブとしてPowerShellのターミナルが開きます。

次に右側の`v`の部分を押下すると下記のようにメニューが表示されます。
![wt004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/3954fc2f-f9d2-2001-634a-1c4ea83c4601.png)
`cmd`を選択すれば、コマンドプロンプトが、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/6ff1523d-0eae-8ade-7abe-fc13551e69f1.png" width="800">
`Ubuntu-18.04`を選択すれば、WSLのUbuntuのターミナルが別タブで開きます。
※WSLのUbuntuをインストールしていた場合。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/4331b4c4-a323-0b3e-f22d-d80ac7b0d2b5.png" width="800">
UbuntuであればSSHも使えますので、SSHのターミナルとしても使えますね。

呼び出すアプリ(powershell.exe, cmd.exe, wsl.exe)もカスタマイズ可能となっているので、
外部サーバーへのSSH接続をメニューに追加しておくといったこともできるような気がします。(未検証ですが。。。

# Windows Terminalのカスタマイズ
Windows Terminalはかなりカスタマイズが可能な仕様になっているようです。
メニューから「Settings」を選択すると、`profiles.json`という設定ファイルが開かれます。
これを編集することにより、キーバインドやフォント、各種色の設定、背景画像なども設定可能なようです。

例えば、

```json
"profiles" : 
    [
        {
            "acrylicOpacity" : 0.5,
            "background" : "#012456",
            "backgroundImage" : "C:\\Windows\\Web\\Wallpaper\\Windows\\img0.jpg",
```
このように`backgroundImage`にWindows10のデフォルト壁紙を指定すると、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/6a59a141-870e-7c80-17fa-ff5e3bffc7ae.png" width="800">
こんな感じになります。
設定次第でいろいろできそうです。
ICT研究開発チーム（Buzzworks）の黎明

##***変わり者とでもバカとでも呼べ。ただし臆病者とは言わせない！***（宮川チーズ祭り）

![IMG_20190108_101055_120.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458322/60e6af12-0b98-e4d8-8f93-5aac7ecf688f.jpeg)

ICT研究開発チームの黎明の物語です。
こうやって俯瞰すると、勢いと思い付きだけだったのは否めませんが、
それでいいと思います、[青春の詩](https://www.instagram.com/p/BsSz-8qjd1D/)です。

##2016年12月
[エンジニア女子（３枚目）](https://www.instagram.com/p/BvTaQaBjgu8/)が「Pythonやりたい」「エンジニア工数単価トップ」と言い出しました。

##2017年04月～
某大学 情報系学部 某研究室（Python研究室）から複数名が入社しました。

##2017年07月～
上記新人達とTeam Python（ICT研究開発チーム）を結成しました。

新人と社長なので五里霧中・・・勢いだけで何をしていいのかわかりませんでした。

某研究室を訪問して、先生に教えを請いました、[Raspberry Pi](https://www.instagram.com/p/BWeaJGnB_XZ/)を紹介されました。

- [ドローン](https://www.instagram.com/p/BXW0nz4BqWq/)購入、自動操縦させようとしましたが、高みを目指しすぎ失敗…
- 取敢えず、ラジコンの[DCモーターコントロール開発](https://www.instagram.com/p/Ba4tvv8BwJ8/)を行いました。
- [GPS装置開発](https://www.instagram.com/p/BbEPON9BOQQ/)、精度が上がらず四苦八苦しました。

新人の[大学卒業研究の延長１](https://www.instagram.com/p/BdG32DyBvur/) [大学卒業研究の延長２](https://www.instagram.com/p/BdG4iqIhVbu/)も実施しました。

Instagramでのまとめは[#中央システムrd](https://www.instagram.com/explore/tags/%E4%B8%AD%E5%A4%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0rd/)

##2017年10月～
メンバーの新人達は順次開発現場へ、うち２名はPython開発を行っています。

##2018年03月～
Team Python→Buzzworksに改名しました、バズる為です。
ネーミングは、[Skunk works](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%AB%E3%83%B3%E3%82%AF%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9)からです。
![Skunk works](https://innovationmanagement.se/wp-content/uploads/2013/03/skunk-works-meets-collaborative-innovation.jpg)
軍事関連とは一切関係ありません、「企業内の極秘開発部門・選抜されたメンバーのみからなる特命チーム」の方です。

[商標登録](https://www.j-platpat.inpit.go.jp/c1800/TR/JP-2018-030573/2CFB8CA3D61EEDC1045B6876C4954B05ABF0463D146EABD56171EED9D555E2B9/40/ja)も行いました（米国も＝Serial Number	79240035）。

##2018年04月～
- 若年者向け教育事業模索 [IchigoJam](https://www.instagram.com/p/Bk3vmUfn-EE/)  [DCモーターコントロール軸でのまとめ](https://www.chuo-system.co.jp/csclib/index.php/2019/06/24/icteducation/)
- オンライン動画教育事業 [Flask速習講座_Part1](https://www.chuo-system.co.jp/csclib/index.php/2019/04/03/flask-part1/)
- メディア施策、[広告宣伝](https://youtu.be/JI9VxB7JOBE)、ブランディング
- [新入社員研修改革](https://www.chuo-system.co.jp/csclib/index.php/2019/07/09/2019-training/)
- [バーチャル社員犬](https://www.chuo-system.co.jp/csclib/index.php/2019/02/20/pie/)

##今後は…
引き続き、
真剣に、楽しく、変な事をやって行きたいです。

##***変わり者とでもバカとでも呼べ。ただし臆病者とは言わせない！***
KerasのSpatialDropout2Dの動作具体例

# 概要

SpatialDropout2Dというのがあるので画像認識で利用を検討したのですが、字面からイメージしたのと違った動作でした。
[先行記事](https://hironsan.hatenablog.com/entry/keras-spatial-dropout)もありますが、画像で使う場合の具体例が出ていないので、こちらでまとめます。

# 具体例

この画像を入力したとして、

![colorbar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191697/2f15c8cc-3148-a059-ac1c-5b6930151fab.png)

これが普通のDropout

![dropout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191697/6bb8a476-db61-436f-3e78-d07129153f1c.png)

これがSpatialDropout2Dです。画像全体で特定のチャンネルをDropする動作です。

![spatial_dropout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191697/d73fd755-543d-9ad2-9805-7e5ec6ae3ec4.png)

私が[Spatial]という字面から想像したのはこういうのでした…。これはdropoutのnoise_shape引数をうまく与えれば実現することができます。

![point_dropout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191697/a0ac810f-ab89-0f71-2b7d-af9e6224fdf7.png)

# 再現用コード

```check_dropout.py
import numpy as np
import cv2
from tensorflow.keras.layers import *
from tensorflow.keras import backend as K

src = cv2.imread("colorbar.png")
height, width = src.shape[:2]

def point_dropout_function(x, drop_rate):
    s = K.shape(x)
    return K.dropout(x, drop_rate, (s[0], s[1], s[2], 1))

K.set_learning_phase(1)  # 実行時にDropout有効化するために必要
x = Input((height, width, 3))
y_dropout = Dropout(0.2)(x)
y_spatial = SpatialDropout2D(0.2)(x)
y_point = Lambda(lambda x: point_dropout_function(x, 0.2))(x)
f = K.function([x], [y_dropout, y_spatial, y_point])

for i in range(10):
    dst_dropout, dst_spatial, dst_point = f([src[None, :, :, :]])

    cv2.imshow("src", src)
    cv2.imshow("dst_dropout", dst_dropout[0])
    cv2.imshow("dst_spatial", dst_spatial[0])
    cv2.imshow("dst_point", dst_point[0])
    cv2.waitKey()

```
mac VSCodeでF12で関数ジャンプまでの道のり

# はじめに
この記事ではmac VSCodeにてショートカットキーF12を押したら関数を定義したところへジャンプしてくれる「関数ジャンプ」機能の設定方法について紹介します。使用言語はRubyを想定しています。

できあがりのイメージは以下のようなものです。

<img width="590" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221909/931e9ff3-6cbb-28ff-18e8-5ff502f09d89.gif">

VSCodeのショートカットを解説した記事のなかには、「タグジャンプ: F12キー」とさらっと書いてあるものもあったのですが、私がやってみると、いくつかのハマりどころがありました。


# 設定方法
## Step1: F12キーを有効にする

デフォルトの状態だとF12キーを押すと音量マークが現れてしまいます。これを無効にしてファンクションキーが有効になるように設定します。

・システム環境設定 →　キーボード → 「キーボード」タブで
「F1,F2などのキーを標準のファンクションキーとして使用」にチェック。

<img width="390" alt="スクリーンショット 2019-07-13 16.24.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221909/6623ba2f-cc6c-8ffb-23a2-661d422cfac3.png">

・システム環境設定 →　キーボード → 「ショートカット」タブ
Dashbordを表示 F12 をチェックを外す。

## Step2: VSCodeのRuby拡張モードをインストールする

・VSCodeの左下の歯車マークから「拡張機能」を選択 → 検索エリアに「Ruby」を入力、インストール

・VSCodeのメニュー:Code → 基本設定 → 設定
Rubyで検索すると、 "Ruby: Intellisense" という項目があるので、これを "rubyLocate" に変更

## Step3: VSCodeを再起動

VSCodeを再起動します。

・・で、いけるはずです。

# まとめ
この記事ではVSCodeにてF12キーで関数ジャンプの手順についてまとめてみました。
他にも便利なショートカットキーがあります。

- [【Mac版】 VisualStudioCode キーボードショートカット](https://qiita.com/naru0504/items/99495c4482cd158ddca8)

ぜひ、参考にしてみてください！
なるはや Vue SPA入門：プロジェクト作成

Vue CLI ver 3 で作成した SPA（Single Page Application）プロジェクト上で、段階的に Vue.js を学んで行きます。

[目次はこちら](https://qiita.com/tsubo/items/24df49ef2f1ba87984d1)

今回はプロジェクト作成編です。

## 前提事項

- node.js が PC にインストールしてあること
- npm or yarn でパッケージ管理ができること（このチュートリアルでは`yarn`を使っていきます）

## Vue CLI 3 セットアップ

パッケージマネージャのグローバル環境に、vue コマンドをインストールします。
インストールが終わると、vue コマンドが使用できるようになります。

```bash

$ npm install -g @vue/cli
# or
$ yarn global add @vue/cli

$ vue --version
```

## プロジェクト作成

vue コマンドでプロジェクトを作成します。

```bash
$ vue create vue-tutorial

? Please pick a preset: (Use arrow keys) 
  default (babel, eslint)
❯ Manually select features
```

`Manually select features` を選択し、今回は以下の項目を選択します。

- Babel
- Router
- Vuex

その後はすべて Yes を選択します。しばらく、インストールに時間がかかります。

## 動作確認

インストールが完了したら `yarn serve` コマンドでPC上で開発用のウェブサーバを起動して Vue アプリを実行します。

```bash
$ cd vue-tutorial
$ yarn serve
```

http://localhost:8080/ にアクセスして`Welcome to Your Vue.js App`が表示されれば、プロジェクトの作成は完了です。

## 次回

[ファイル構成](https://qiita.com/tsubo/items/579daa4f1b45f13b8175)です。
[WPF][XAML]DataGridの行高さを自動調整する

行数固定のDataGridを目一杯広げて表示したかったけど、結構調べても出てこなかったのでメモ。

つぎのようにスタイルを設定してもビルドエラーとなったりと期待通りにならない。

```MyDataGrid.xaml
<DataGrid CanUserAddRows="False" CanUserDeleteRows="False">
    <DataGrid.RowHeaderStyle>
        <Style TargetType="DataGridRowHeader">
            <Setter Property="Height" Value="*"/> <!--ビルドできない Value="Auto" もダメ-->
        </Style>
    </DataGrid.RowHeaderStyle>
</DataGrid>
```

仕方ないのでXamlで書くのは諦め、イベントで処理します。

```MyDataGrid.xaml
<DataGrid Name="myDataGrid" CanUserAddRows="False" CanUserDeleteRows="False"
          SizeChanged="MyDataGrid_SizeChanged">
</DataGrid>
```
```MyDataGrid.xaml.cs
//myDataGridのサイズが変わるたびに行の高さを再設定する
private void MyDataGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
    myDataGrid.ColumnHeaderHeight = 20; // 列ヘッダがある場合は適当な値を入れます
    
    // 行数が5の場合
    var hoge = 2; // 行数で割るだけだとちょっとはみ出るので微調整
    myDataGrid.RowHeight = (myDataGrid.ActualHeight - myDataGrid.ColumnHeaderHeight) / 5 - hoge;
}
```
これで行高さが自動調整されます。

ところが、最終行やマウスホイールを動かすとスクロールするときがあります。そんなときはScrollViewer.CanContentScrollをFalseにして強制的にスクロールを禁止します。

```MyDataGrid.xaml
<DataGrid Name="myDataGrid" CanUserAddRows="False" CanUserDeleteRows="False"
          SizeChanged="MyDataGrid_SizeChanged"
		  ScrollViewer.CanContentScroll="False">
</DataGrid>
```
これでOK
Google App Engine上のアプリを段階的にリニューアルする

## 現状とやりたいこと

Google App Engine Pythonで作成された、古いアプリケーションがあります。
これがRESTとかも何も知らない頃に、独自に考えてAPIを作ったので、クライアント側などで無理が出てきました。（レスポンスがJSONじゃないのでパースし辛いなど）

この際にAPIを一新し、Webフロントエンド・iOS・Androidのそれぞれからのリクエストもそちらに切り替えたくなりました。
ただ、アプリ側には強制バージョンアップ機能などもなく、並行動作させる期間を設けたいと考えました。[^1]
（数ヶ月ぐらい並行稼動してれば、それなりにアクティブなユーザはアプリを更新してくれるだろう、と割り切ります。）

[^1]: 強制バージョンアップがあったとしても、開発側からのアプリ公開してから、全ユーザが新しいアプリを利用可能になるまでのラグがあり、それを開発側からはコントロールできないので、長時間のサービス停止が必要になってしまいます。

Google App Engineと同一プロジェクト内のCloud Datastoreを利用しており、そこは引き続き利用したいと思います。

## 手順イメージ

Google App Engineのserviceを新規に作成することとしました。

1. 既存のプロジェクト内に、新規サービスとして `v2` を作成し、そこに既存と同等の機能を持つAPIを実装。
2. 既存サービスとv2を並行稼動させ、 `/v2` 以下のリクエストについては、v2サービス側に流す。
3. iOS・Androidのクライアントからは、v2を利用するように変更、リリースする。

この状態でのイメージ図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8708/ae0680ec-3e76-9eaf-088c-c749f2d57dc1.png)

<!--
@startuml
[Web frontend]
[old iOS/Android app]
[iOS/Android app]

package "GAE project" {
  [Default]
  [v2]

  database {
    [Datastore]
  }
}

[Web frontend] ..> [Default]
[old iOS/Android app] ..> [Default]
[iOS/Android app] ..> [v2]
[Default] ..> [Datastore]
[v2] ..> [Datastore]
@enduml
-->

そのあと、

1. v2上で新しいフロントエンドを作成。（APIリクエストもv2に向ける）
2. すべてのリクエストがv2サービスに流れるように変更。（古いアプリからはアクセス不可になる）
3. 既存サービスを停止する。

この状態でのイメージ図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8708/eea2856e-5a1a-9d11-fb73-8fd5ea87a26b.png)

<!--
@startuml
[Web frontend]
[old iOS/Android app]
[iOS/Android app]

package "GAE project" {
  [v2]

  database {
    [Datastore]
  }
}

[Web frontend] ..> [v2]
[iOS/Android app] ..> [v2]
[v2] ..> [Datastore]
@enduml
-->

## 具体的な要素技術

### 複数のサービスを共存させる

`app.yaml` に `service` を指定することで、別サービスとして並行稼動させることができます。

ドキュメント： https://cloud.google.com/appengine/docs/standard/python/config/appref?hl=ja

何も指定していないと、 `default` というサービスで起動されます。

サービスごとに全く別のコードベース・Runtimeを利用することもできます。
（今回も、既存はPythonですが、新規APIはGoで実装中です）

### URLを振り分ける

iOS/Androidアプリからの利用を想定すると、ドメイン・パスの変更回数は減らしたいです。
既存サービスの有無に関わらず、同一ドメイン・パスでアクセスし続けられれば良さそうです。

そこで、新しいAPIは `/v2` 以下のパスに作成し、既存のドメインでも `/v2` 以下のリクエストはv2サービスに振り分けます。

そのため、まずは `dispatch.yaml` というファイルを新たに下記のように作成しました。

```yaml
dispatch:
  - url: "*/v2/*"
    service: v2
```

次に、これをデプロイします。

```sh
gcloud app deploy dispatch.yaml
```

これにより、既存ドメインの `/v2` 以下にアクセスすると、v2サービスが実行されることになります。

ドキュメント: https://cloud.google.com/appengine/docs/standard/go/reference/dispatch-yaml?hl=ja
Railsコンソールについて　allメソッド使用時にコマンド入力を受け付けなくなった際の対処法　

# はじめに
###・コンソールとは
ターミナル上で、Railsで定義されているメソッドを使用し確認ができる機能のこと

・コンソールを使用するにはターミナルで以下を入力します。

```
rails c
```

すると以下の様になり、コマンド受付状態になります。

```
[1] pry(main)> 
```
・コンソールを終了するにはコンソールで以下入力します。

```
[1] pry(main)> exit
```

またはCtrl + Zを入力しても終了させることができます。

#問題の現象について
##・allメソッド使用時にコマンド入力を受け付けなくなる現象について

コンソール上でallメソッドを使用した際にDB上の値が
多すぎる場合以下の様に、処理が途中であるかのような状態になります。


```
 #<Product:0x00007f94d923af58
  id: 2,
  title: "フェリシーと夢のトウシューズ",
  image_url: "http://eiga.k-img.com/images/movie/86684/photo/e488779e0ed18eb9/320.jpg?1499740950",
  created_at: Sun, 30 Jun 2019 07:35:25 UTC +00:00,
  updated_at: Sun, 30 Jun 2019 08:43:23 UTC +00:00,
  director: "エリック・サマー",
  :｜

```

これはallメソッドで取得してきた値が多すぎるため表示を途中で終わらせているためです。
ただ、この状態で次のコマンドを入力しようとすると

```
No next tag  (press RETURN)
```
が表示され、コマンドが入力できません。

##対処方法

この場合はキーボード「Q」を入力してください。

すると以下のように

```
[2] pry(main)> 
```
となり、次のコマンドを入力できるようになります。

#おわりに

処理を終わらせたり、処理の途中で終了させるのは
exit入力かCtrl + Cの二通りと勝手に思い込んでいたので
この現象にあったときは混乱しました笑

この投稿が初めてとなりますので
至らぬ点もあるかと思いますが、誰かのお役に立てられれば
幸いです。
SpringでGETリクエストを複雑なオブジェクトにマッピングする。

# やりたいこと（目的）
SpringのGETリクエスト（URLパラメータ）を複雑なオブジェクト（Bean）にマッピングする。

- ネスト構造
- リスト構造

# 結論
Mapping用のアノテーションを使用しない。
または
`@ModelAttribute`を使用する。

※変数名とURLパラメータのキーを合わせる必要あり。

# 環境
Spring Boot:2.1.6
### その他使用ライブラリ
lombok

## テキトーな検証ソース

### マッピング先
親オブジェクト

```java
@Data
@ToString
public class ComplexBean {
  private String hoge;
  private ChildBean childBean;
  private List<ItemBean> itemBeans;
}
```
ネスト用の子オブジェクト

```java
@Data
@ToString
public class ChildBean {
  private String piyo;
}
```
リスト用のオブジェクト

```java
@Data
@ToString
public class ItemBean {
  private String fuga;
}
```
※`@Data`,`@ToString`はlombokのアノテーション
`@ToString`は検証用

### コントローラ
```java
@RestController
public class DemoRestController {

  @GetMapping(value = "/param")
  @ResponseBody
  public String getParam(@RequestParam ComplexBean bean) {
    System.out.println(bean.toString());
    return bean.toString();
  }

  @GetMapping(value = "/model")
  @ResponseBody
  public String getModel(@ModelAttribute ComplexBean bean) {
    System.out.println(bean.toString());
    return bean.toString();
  }

  @GetMapping(value = "/direct")
  @ResponseBody
  public String getDirect(ComplexBean bean) {
    System.out.println(bean.toString());
    return bean.toString();
  }
}
```

# 検証
Restlet Client - REST API Testingを用いて各エンドポイントにアクセス

## 検証するURLパラメータ
`hoge=hoge&childBean.piyo=piyo&itemBeans[0].fuga=fuga0&itemBeans[2].fuga=fuga2`

## 結果
`@RequestParam `を使用する場合
(`http://localhost:8080/param?hoge=hoge&childBean.piyo=piyo&itemBeans[0].fuga=fuga0&itemBeans[2].fuga=fuga2`)
マッピング情報が足りないのでパースできずエラーになる。

```
Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required ComplexBean parameter 'bean' is not present]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365356/aecc2489-27f4-b395-8749-7041ea7da164.png)

`@ModelAttribute`を使用する場合
(`http://localhost:8080/model?hoge=hoge&childBean.piyo=piyo&itemBeans[0].fuga=fuga0&itemBeans[2].fuga=fuga2`)
想定どおりマッピングされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365356/480baece-198e-031f-ab5e-d99d8ce749ef.png)

アノテーションなしの場合
(`http://localhost:8080/direct?hoge=hoge&childBean.piyo=piyo&itemBeans[0].fuga=fuga0&itemBeans[2].fuga=fuga2`)
想定どおりマッピングされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365356/4425a374-9ad1-25e8-122c-afd6261cd2b3.png)

# まとめ
以下の構造を持つURLパラメータでも
- ネスト構造
- リスト構造

Mapping用のアノテーションを使用しない。
または
`@ModelAttribute`を使用する。

とすればマッピングできる~~がGETのリクエストでこんなオブジェクトにマッピングしなきゃいけなくなった時点で設計を見直そう~~。
なお、検証のように配列番号を飛ばした場合は飛ばされた枝番は`null`が設定される。（⇒空のオブジェクトにはならない）
Javaの学習に使用した書籍

随時更新
簡単な感想程度

前提
C言語でポインタまで学習
PHPでDBから値を取得する掲示板が作れる
ASP.netとLaravelを触ったことがある、程度

#Java
####**[1.スッキリわかるJava入門 第2版](https://www.amazon.co.jp/dp/484433638X/ref=emc_b_5_i)**
スッキリ本1冊目
1週目読んだときはオブジェクト指向のオブまでしか分かりませんでした。(当時はCしかやっていなかった)
一旦Progateを挟んで読み直すと、なんとなく頭に入りました。
Javaからプログラミングを学ぶ人にも進められる一冊です。
学習範囲：プログラミング基礎(配列やポインタ等)、オブジェクト指向

####**[2.スッキリわかる Java入門 実践編 第2版](https://www.amazon.co.jp/dp/4844336770/ref=pd_sbs_14_1/)**
スッキリ本2冊目
上記の本では触れられなかった業務で実際に使われるであろうAPIがメイン。
Junitやデザインパターン、実際の業務での話にも触れています。
今からJavaを学び始めるのであれば、上の入門と合わせて間違いではない2冊だと思います。
学習範囲：Javaの基本機能(コレクションやジェネリクス等)、DB連携

####**[3.スッキリわかるサーブレット&JSP入門 第2版] (https://www.amazon.co.jp/dp/4295005940/ref=pd_sbs_14_2/)**
スッキリ本3冊目
Javaだけでなく、HTMLとSQLがわかってることが前提です(Webアプリケーションなので)
2番の実践編と同様にH2DBが使用されているので、流れのままにやると勉強しやすいです。
学習で躓かないように作られている分、DB接続して値を取得するところまでしか行いません。ここから発展させていくのは一度別に何か作った経験がないと厳しそうに感じました。
学習範囲：jsp/servlet、MVCパターン、dao、設計

####**[4.徹底攻略 Java SE 8 Silver 問題集](https://www.amazon.co.jp/dp/4844339931/)**
所謂黒本
Java Silverを取得するためだけの本…の予定でしたがコンストラクタの動きやオブジェクト指向でのコードなど、今まで分かった気になっていた部分が明確になった本。一番勉強になった気がします。ここで基礎的な部分を抑えるために資格勉強は良いものだと理解しました。
(要点だけ抜き出した優しい公式Docを読んでる気分)
学習範囲：オブジェクト指向（他JavaSilver範囲）

####**[5. 徹底攻略 Java SE 8 Gold 問題集](https://www.amazon.co.jp/dp/4295000035/)**
Goldの黒本
Silverの勉強が身になったので勢いでGoldの勉強を始めました。最初読んでいてStream、並行性、I/O分かりませんとなったので後悔。下記の6,7と並行して読む事で、言葉の意味が理解できるようになりました。
解説の図によってイメージが湧きやすいので、やはり基礎を抑えるにはとても良い本だと思います。
学習範囲：StreamAPI、並行性、JavaI/O(他JavaGold範囲)

####**[6.Java本格入門 モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで](https://www.amazon.co.jp/dp/477418909X/ref=pd_sbs_14_6/)**
現場でのJava~という文言があったので購入。2のJava入門実践編と範囲が似ていますが、語り口が違うので2冊ともやるのが良いと思います。(欲を言えば同じ内容に関して3冊やりたい) 無駄のないコードの書き方にも触れていて、どんなコードを書くかが意識しやすいです。
また、Java7以前の書き方にも触れているのが一番良いポイント(業務がJava8じゃなくても安心(?))
学習範囲：2番の実践編と同等

####**[7.オラクル認定資格教科書 Javaプログラマ Gold SE 8](https://www.amazon.co.jp/dp/479814682X/ref=pd_sbs_14_2/)**
所謂紫本
黒本が完全に問題集で試験が不安になったので教科書である紫本を購入。ちょっと説明が多いかな？と思う分内容は濃いです。資格に受かるだけなら黒本だけで良いかもしれませんが、内容をしっかり理解するなら紫本も必要だと感じました。
まだGold受けてません。
学習範囲：5番の黒本と同等

#プログラミング共通本
[リーダブルコード](https://www.amazon.co.jp/dp/4873115655/ref=sr_1_1?__mk_ja_JP)

#積み本
[オブジェクト指向開発トレーニングブック](https://www.amazon.co.jp/dp/4774137170)(第３章まで)
[ハッカーと画家](https://www.amazon.co.jp/dp/4274065979)(第８章まで)

#読みたいもの(未購入)
[Webを支える技術](https://www.amazon.co.jp/dp/B07JK7FZH2)
[マスタリングTCP/IP](https://www.amazon.co.jp/dp/4274068765/)
[Java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/dp/4797327030)
[JUnit実践入門](https://www.amazon.co.jp/dp/477415377X/)
[Javaビルドツール入門](https://www.amazon.co.jp/dp/4798049387)
[Spring徹底入門](https://www.amazon.co.jp/dp/4798142476/)
[Spring Boot 2 プログラミング入門](https://www.amazon.co.jp/dp/4798053473)

今はとにかく基礎を固めているので、JavaGoldが終了したら設計やデザインパターンを学びたい。
(2019/7/13時点)
改めてみると入門書が多すぎる。
ラズパイ3にPi Cameraをセットして写真撮影

## 前提

- Macで作業している
- ラズパイ3はOSセットアップ済みとする。
- Pi Camera はv2を購入（当然か）
- すべてssh接続越しに作業します。

## まずカメラを装着

必ずラズパイの電源は落としておきましょう。
まず注意してほしいのが、カメラの差し口は画像の場所である。

<img width="640" alt="raspberrypi3_camera.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52227/be84b18b-0285-ab1f-2249-4650c38c443c.jpeg">

ちゃんとラズパイの基盤の文字を見ればわかるが、薄暗い部屋で作業していたおかげで差し口を間違えていた。。。

装着し終わったらラズパイの電源をONにし、sshで接続しておく。

## カメラを有効にする

```
$ sudo raspi-config
```


ラズパイでカメラの信号を受け取れるようにするため、
`Interfacing Options > Camera > <Yes>` を選択する。

ここで一旦ラズパイを再起動する。

## カメラの接続確認

カメラが認識されているか確認するため、以下のコマンドをターミナルで実行

```
$ vcgencmd get_camera

supported=1 detected=0 ←これはNG、カメラが検出されていないの
supported=1 detected=1 ←これがOK、認識されている
```

detected=0 となったら、ケーブルの差し口を確認する。
- 差し口を間違えていないか？
- 前後が逆になってないか？
- 浅くケーブルをさしてないか？

どうしても解決しない場合はカーネルが古い場合があるので、更新してみよう。

```
$ sudo rpi-update
$ sudo reboot
```

## カメラで撮影

撮影はメチャ簡単

```
$ raspistill -o image.jpg
```
エラーメッセージがでなければ撮影成功している。
`-o`でファイル名を指定しており、`image.jpg`という画像名で撮影できているはず。

逆に `mmal: 〜`とメッセージがでる時は何かしらエラーが起きている。
カメラのエラーについては以下サイトが参考になった。
[PiCam異常時の現象](https://research.itplants.com/?p=1617)

## カメラ画像の確認
ssh越しに画像を確認するために`feh`という画像ビューアをラズパイにインストールする。

```
$ sudo apt-get install feh -y
```

インストール後、以下コマンドでssh越しに画像を表示できる。

```
$ feh tmp.jpg
```
こんな表示で画像が確認できる。

<img width="640" alt="スクリーンショット 2019-07-13 16.42.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52227/5dfc86e5-fdb0-f120-b770-6c0f6de6bbec.png">
我が家の天井が映っている...

もしmacで以下のエラーが出た場合

```
feh ERROR: Can't open X display. It *is* running, yeah?
```
この記事を参考にしてほしい
http://banbara-studio.hatenablog.com/entry/2017/08/06/135942

簡単に書くと

- XQuartzをインストールする
- ssh接続時に`-X`を付与して接続しなおす

これでssh越しfehが起動するはず！
【自分用メモ】文字コード


## ツール
* 変換ツール
  *  https://so-zou.jp/web-app/text/encode-decode/


## 参考サイト
* 文字コードの考え方から理解するUnicodeとUTF-8の違い
    * http://equj65.net/tech/charcode/
* 文字コード入門
    *  https://qiita.com/nh321/items/b6acc3cef20bea29bd3b
* 本当は怖い文字コードの話
    *  http://gihyo.jp/admin/serial/01/charcode/0004


## 用語

### 文字コード
* 符号化文字集合(character set)と符号化方式(character encoding scheme)をまとめた概念
* UnicodeとUTF-8・UTF-16・UTF-32の違いとは
    * https://elite-lane.com/difference-between-unicode-and-utf-8-and-utf-16-and-utf-32/

### 符号化文字集合(character set)
* Unicode, JIS, KS, ...
* 一つ一つの文字に、符号位置(コードポイント)と呼ばれる整数値をつけて管理
    * Unicodeの"あ" -> U+3042
    * JIS X 0208 の"あ" -> 4区2点
* 符号位置は符号空間の座標
    * 群、面、区、点

### 符号化方式(Character Encoding Scheme, CES)
* 符号化文字集合で文字に対応づけた整数値を、コンピュータが利用できるデータ列（通常、バイト列）に変換し符号化(Encoding)する方式
* ShiftJIS, EUC-JP, ISO-2022-JP, UTF-8, UTF-16, ...

### Unicode
* 世界中の文字を扱えるようにした符号化文字集合
* 基本多言語面(Basic Multilingual Plane: BMP)

### UTF-8, UTF-16, UTF-32
* それぞれ、8bit, 16bit, 32bit 単位で符号化した符号化方式
* UTF-8
    * 符号位置(コードポイント)によって長さが1~4bytesに変化する可変長の符号化方式
    * ASCII(半角文字)にしか対応していないシステムでも、大きな変更なしに使える 
    * ファイルへの保存や通信に便利で、メモリ効率も高い
    * 可変長のためにプログラムからの操作には不便
* UTF-16
    * サロゲートペアを利用
* UTF-32
    * サロゲートペアを使わずに固定長で表現する
    * 

### ビッグエンディアンとリトルエンディアン
* http://www.torutk.com/projects/swe/wiki/ビッグエンディアンとリトルエンディアン
* リトル：かいバイトからさかさまに並べる方式

### MSB/LSB (MostSignificant Bit/Least Significant Bit)
* https://ja-support.renesas.com/knowledgeBase/17793441

### BOM(Byte Order Mark)
* テキストの先頭にて、どちらのエンディアンかを示すマーク
* ビッグ: FE FF, リトル: FF FE
 

### Unicodeエスケープ
* なぜ？
    * http://una.soragoto.net/topics/12.html
* Php json_encode
    * デフォルトでunicodeエスケープする
    * JSON_UNESCAPED_UNICODEフラグで回避可能

## 書籍
* [改訂新版]プログラマのための文字コード技術入門
  *  https://www.amazon.co.jp/改訂新版-プログラマのための文字コード技術入門-WEB-PRESS-plusシリーズ/dp/4297102919
ユーザー登録画面を作成しながらDBを操作する画面作成の基礎を勉強してみる～ユーザー一覧画面の作成～

ユーザー一覧画面を作成します。
こんなイメージです。[文字]はリンクかボタンを考えています。

---
[新規作成]

|ID|氏名|メールアドレス||||
|:--|:--|:--|:--|:--|:--|
|1	|井高 さゆり	|rika.aota@example.org|[参照]|[編集]|[削除]|
|2	|佐藤 結衣	|sishida@example.net|[参照]|[編集]|[削除]|
|3	|坂本 篤司	|naoki.sasada@example.com|[参照]|[編集]|[削除]|
|4	|若松 直樹	|osamu03@example.net|[参照]|[編集]|[削除]|
|5	|鈴木 太一	|rika68@example.org|[参照]|[編集]|[削除]|
|6	|加納 太一	|ukobayashi@example.net|[参照]|[編集]|[削除]|
|7	|斉藤 明美	|kanou.kana@example.com|[参照]|[編集]|[削除]|
|8	|小泉 修平	|suzuki.naoto@example.org|[参照]|[編集]|[削除]|
|9	|松本 浩	|aoyama.mikako@example.org|[参照]|[編集]|[削除]|
|10	|三宅 知実	|manabu00@example.net|[参照]|[編集]|[削除]|
---

## 手順

 1. コントローラを編集します
 2. 画面を作成します

## 1. コントローラを編集します

一覧画面表示メソッドを修正します。
ユーザーテーブルから全件取得して、取得したデータを画面に渡します。
`User::all()`と記述することにより、モデルテーブルの全レコードをコレクションとして取得できます。

```php:app/Http/Controllers/UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UserController extends Controller
{
    // 一覧画面表示
    public function index(Request $request)
    {
        # usersテーブルのレコードを全件取得します
        $users = User::all();
        # viewに渡すエラー変数
        $errors = array();
        # Viewファイルをuser/index.blade.phpに指定します
        # データを連想配列に代入して渡します
        return view('users.index', ['users' => $users, 'errors' => $errors]);
    }
}
```

## 2. 画面を作成します

画面を追加します。htmlの詳細は割愛します。
`{{ csrf_field() }}`はCSRF保護のためFORMに埋め込む必要があります。
`{{ method_field('DELETE') }}`はDELETEメソッドを送信するために必要です。PUTメソッドを送信したい場合は、`{{ method_field('PUT') }}`となります。
それぞれ、5.6以降であれば`@csrf`と`@method('DELETE')`のように記述できます。

```html:resources/view/users/index.blade.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <div class="row p-1">
        <div class="col">
          <a class="btn btn-secondary" href="/users/create">新規作成</a>
        </div>
      </div>
      <div class="row p-1">
        <div class="col">
          <table class="table">
          <tr><th>ID</th><th>氏名</th><th>メールアドレス</th><th></th><th></th><th></th></tr>
          @foreach($users as $user)
          <tr>
            <td>{{ $user->id }}</td>
            <td>{{ $user->name }}</td>
            <td>{{ $user->email }}</td>
            <td><a class="btn btn-secondary" href="/users/{{ $user->id }}">参照</a></td>
            <td><a class="btn btn-secondary" href="/users/{{ $user->id }}/edit">編集</a></td>
            <td>
              <form method="post" action="/users/{{ $user->id }}">
                {{ csrf_field() }}
                {{ method_field('DELETE') }}
                <input class="btn btn-secondary" type="submit" value="削除">
              </form>
            </td>
          </tr>
         @endforeach
          </table>
        </div>
      </div>
    </div>
  </body>
</html>
```

ブラウザで`http://homestead.test/users`にアクセスするとデータベースに登録されているユーザーが画面に一覧表示されるはずです。


## 参考
[【Laravel】DBの内容をブラウザに表示する方法](https://soma-engineering.com/coding/php/display-contents-view/2018/06/18/)
JFreeChart-積上バーチャート-DefaultCategoryDataset-特定データの強調


目次 ⇒ [JFreeChartサンプル](https://qiita.com/artery/items/3e9c63e5c14a9e965c97)

```java
package jp.avaj.lib.chart;

import java.util.ArrayList;
import java.util.List;

import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.data.category.DefaultCategoryDataset;

import jp.avaj.lib.algo.ArTuple;
import jp.avaj.lib.algo.ArUtil;

/**
■ JFreeChart-積上バーチャート-DefaultCategoryDataset-特定データの強調

・積上バーチャートでは一番下以外のデータは変化が分かりにくいので、順番を入れ替え一番下に表示してみる.

・問題点、色が前と変化するので分かりにくい.rotateRowを汎用的に作る必要がある.
  ・しかし方式は確認できた.
 */
public class Chart08_02 {
  // 目次-積上げバーチャート(StackedBarChart)
  A_Chart08 a_Chart08;
  // 目次-Artery-JFreeChart用のライブラリ
  A_Chart00 a_LibChartSampeContents;

  public static void main(String[] args) {
    // 表示データの作成
    DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
    {
      //
      dataSet.addValue(136.5,"商品A","2014");
      dataSet.addValue(206.1,"商品A","2015");
      dataSet.addValue(296.7,"商品A","2016");
      //
      dataSet.addValue( 40.5,"商品B","2014");
      dataSet.addValue(105.7,"商品B","2015");
      dataSet.addValue(199.4,"商品B","2016");
      //
      dataSet.addValue(150.5,"商品C","2014");
      dataSet.addValue(87.5,"商品C","2015");
      dataSet.addValue(40.0,"商品C","2016");
    }
    //
    CategoryAxis catAxis = new CategoryAxis();
    NumberAxis numAxis = new NumberAxis();
    // 積上棒グラフにはStackedBarRendererを使用する
    StackedBarRenderer renderer = new StackedBarRenderer();
    CategoryPlot catPlot = new CategoryPlot(dataSet,catAxis,numAxis,(CategoryItemRenderer)renderer); // (1)
    JFreeChart jfreeChart = new JFreeChart("売上構成の変化",(Plot)catPlot);
    //
    ChartFrame cFrame = new ChartFrame("売上構成の変化",(JFreeChart)jfreeChart);
    cFrame.pack();
    cFrame.setVisible(true);
    //
    // 商品Bの売上の変化を掴みたいので、商品Bを一番下に表示する
    {
      // 目で確認するために、少し休む
      ArUtil.sleep(2000);
      //
      rotateRow(dataSet);
    }
  }
  private static void rotateRow(DefaultCategoryDataset dataSet) {
    int colms = dataSet.getColumnCount();
    Comparable rowKey = dataSet.getRowKey(0);
    List<ArTuple> values = new ArrayList();
    for (int col=0; col<colms; col++) {
      Comparable colKey = dataSet.getColumnKey(col);
      values.add(new ArTuple(colKey,dataSet.getValue(rowKey,colKey)));
    }
    dataSet.removeRow(rowKey);
    for (int i=0; i<values.size(); i++) {
      dataSet.addValue((Double)(values.get(i).getV1()),rowKey,(Comparable)values.get(i).getV0());
    }
  }
}

```
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278568/c4df489c-0ade-d805-329b-36625257d46d.png)


![無題-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278568/2583f1a0-98fb-e431-50e4-fe3de0012086.png)
ストアドプロシージャでビジネスロジックを書く利点・欠点

# はじめに
基幹系システムの開発に携わり、ビジネスロジックをT-SQLとPL/SQLで書いてきました。
ビジネスロジックをストアドプロシージャ上に実装することについて、思ったことを書いておきます。

# 利点
#### アプリケーション全体のアーキテクチャをシンプルにできる
ビジネスロジックとUIが物理的に分かれるので、フレームワークやデザインパターンに精通せずとも、レイヤー構造を作れます。
#### プログラマのスキルに差があっても品質に影響しにくい
良くも悪くもストアドプロシージャは自由度が低いです。誰が書いても同じコードになりやすいです。
#### 分業がしやすい
ビジネスロジックとUIが完全に分かれているので、誰が何をするのかが明確になります。言語も違いますからね。
#### パフォーマンスが悪化しにくい
 DB側で実行されるので、アプリサーバ－とDBサーバ間のラウンドトリップを気にする必要がありません。ORMのN+1問題などとも無縁です。
		
# 欠点
#### 開発環境が貧弱
開発はDB管理用のソフト(SSMS, SQL Developerなど)で行うので、基本オマケ機能です。開発支援機能が少なく、コードの追跡やデバッグは大変です。
#### 言語機能が貧弱
基本的に手続き型で、機能も少ないので長いコードになります。重複コードが発生しやすいです。
#### RDBMSを変更できない
ストアドプロシージャは製品固有の言語で記述されるため、ベンダロックイン状態になります。DBの変更が無い環境であれば特に問題にはなりませんが。
#### バージョン管理システムに乗せるのが難しい
DB上にプログラムが格納されるので、バージョン管理システムとは相性が悪いです。
#### 自動ユニットテストの導入が困難
ビジネスロジックとDBが密結合していますので、xUnitのような仕組みの導入が難しいです。CI/CDは夢のまた夢かもしれません。

# まとめ
ストアドプロシージャへの悪口を並べたような恰好になりましたが、組織によっては、ストアドプロシージャの方が向いている場合もある、ということが言いたかったです。
しかしながら、RDBMSとの結合度の高さは、様々なしがらみを生み出します。これをよしとするかの判断が必要になります。
GithubからクローンしてきたAndroidプロジェクトがGradle sync failed: Already disposed: Module:で認識されない時の対処法

# 背景
Githubからクローンしたプロジェクトをビルドしようとしたところ、`Gradle sync failed: Already disposed: Module:`というエラーが発生してモジュールが認識されませんでした。

# 参考
https://stackoverflow.com/a/50430517

# 対応
>Quick Solution: In order to make it work the easiest is to delete .idea/modules.xml along with the  .iml files. Additionally may worth deleting .idea/modules/ folder if it exists. Restart Android Studio (no need to clear cache) and force a Gradle sync from Gradle view or toolbar to recreate the files.
https://stackoverflow.com/a/50430517 より引用。

上記引用文の通り、`.idea/modules.xml`と`.iml`を削除し、AndroidStudioを再起動、その後該当プロジェクトを開きなおすと正常に認識されました。
Material Design における色

## 色の選択

Material Designに則った色の選択方法の要点は下の画像に詰まっています。
これから、この画像を見ながら説明していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415097/36181b79-af9d-f6d4-671f-53f35d3b72f0.png)

## メインのブランド色
[画像](#色の選択)を見ると、１と２は色が似ていることが分かります。
そして、Primaryと書かれています。
この二つの色はあなたが作るアプリ全体を通して使う色で、あなたのアプリのブランド色となります。
これらはアプリの中で重要なコンポーネント、例えばヘッダー等で使われます。
下の画像に利用例が示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415097/f5b32937-da60-f223-6e6e-10a1fd5b292b.png)


## 補助的なブランド色
再び[画像](#色の選択)を見ると、3と4も色が似ていてSecondaryと書かれていることに気づきます。
この二つの色は、アプリ内において補助的なブランド色として使われます。
たとえばボタンやセレクションなどのUI部品に使うのが良いみたいです。
下の画像ではボタンの色に使われています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415097/2c2360a4-54bc-95a7-9670-7f4647f3f359.png)

## その他の色
[画像](#色の選択)内の5から7はそれぞれ、背景色、汎用的なコンポーネント（カードやメニュー等）の色、UIのエラーを伝える色を表しています。
アプリ内で幅広く使われる色は5と6の色になります。
下の画像ではブランド色は省かれた状態で、上の3つの色の利用例が示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415097/20baa4fa-57bf-f555-cf34-9580c393f4eb.png)

## 文字やアイコンの色
[画像](#色の選択)内の8から12は、1から7のコンポーネントの上での文字やアイコンの色を表しています。
それぞれOn Primaryのように、それぞれの頭にOnということがついています。
例えば、On Primaryは白色で、Primaryは濃い青色です。
これは濃い青色の上では白色の文字が見やすいためにそのように選択されています。
他の色も同様の考え方で白か黒かを決めます。

下の画像ではそれぞれのコンポーネントの上の文字や色について意識してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415097/afb646a7-730c-68e6-7470-767ec64ff9de.png)

## まとめ
アプリ内の色を選ぶとき、まずはメインのブランド色を選びます。そして、もう一つブランド色が欲しい時には、補助的なブランド色を選びます。これらは似てない色を選択したほうが良いです。
そして、背景色や汎用的なコンポーネントや文字などは、このブランド色の邪魔をしない色を選ぶようにします。

# 参考文献
[The Color System](https://material.io/design/color/the-color-system.html#color-usage-palettes)
小学2年生にプログラムをさせてみた その２

#前回までのようす
https://qiita.com/fu-jimoto/items/4f96a02934aae37a3040

#タイピングについて
HTMLやjavascriptを教えるのことはできました。
ですが、やはりタイピングができないと作業がはかどりません。
タイピングをマスターする為にいろいろ試しました。
![IMG_20190713_131541.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/21d653ff-819c-ab5b-f714-69f6156e3786.jpeg)



[FMVキッズのめざせタイピングマスター(Web)](http://azby.fmworld.net/kids/typing/)
どの指を使ってタイプするか表示されるので非常にいいアプリだと思います。
ですが、息子はあまりはまらず。。。

[寿司打(Web)](http://typing.sakura.ne.jp/sushida/)
流れていく寿司のネタをタイプしていきます。
キーボードのサポートがないので少し難しくなります。
基本的にオンラインのタイピングソフトはFlash製がほとんどですが、この作者はWebGL版もリリースいているようです。
息子あまりはまらず。。。

[のりものタイピング(app)](https://apps.apple.com/jp/app/%E3%81%AE%E3%82%8A%E3%82%82%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0/id1222383247)
一部無料のアプリです。正しく操作できると車が進んでいきます。
ですが、キーボードサポートがあり、文字よりも場所だけでタイプするような仕様なので文字入力が覚えれるかは微妙です。全機能を使うには1,200円必要です。
息子少しはまりました。

~~[侍道3(web)](#)~~　→終了
ゲーム要素（見た目）が強いとはまるかなと思い試しました。
ですが、入力が遅いとバッサバッサ攻撃されるので途中で投げ出しました。
難しい事から敬遠しがちな点が気になります。
当然のごとくはまらず。。。

[狙撃タイピング(web)](http://typing.sakura.ne.jp/sushida/simple/shot.html)
アルファベットの的を撃っていきます。
割とシンプルで男の子が好きそうな雰囲気です。
息子は少しはまりました。

##方針
息子は以下の傾向にあるので継続させる事が課題になりそうです。
・難しい事は敬遠がち
・飽きっぽい


ひとまず「のりものタイピング」「狙撃タイピング」で練習させようと思います。
また、スマホでググる(LaQのサンプル調査とか）事はある程度できているので、これから調べ物はPCでやらせてみようと思います。


#作業PCについて
始めたタイミングでは私のMacをさわらせていました。
ですが、つきっきりでないといけないのでどうしようかなと悩みましたが、よくよく考えたら使ってないmac bookが一台余っていました。

##spec
・MacBookPro 13-inc Mid2009 (古い。。。）
・Core2 Duo 2.26GHz
・Memory 2G(4Gではなくて・・・？？？)
・OS X El Capitan
・故障箇所 
 (1)Wi-Fi。USBのWi-Fiアダプタで代替。
 (2)OSの起動。たまに失敗する。
10年前の機種ですが、お勉強にはまあいいかなと思います。ちょっとメモリーだけ心細いのでamazonで購入中です。
とりあえず、今の重たい状況を体験させつつ、メモリー増設したらどうなるかも体験させて、CPUとメモリーの説明もしようと思ってます。
2019/7/23 追記:メモリー8Gになりました。


#「ググる」ということを教える
今ではコーディングをするにあたって、本よりもググる事が大事だと僕は思ってます。
子供にもググる事を覚える為（ついでにタイピングも覚える為）に今本人が欲しいと思っているGPS機能付きの腕時計でリストアップ作業をさせました。
基本的に飽きっぽいので、ちゃんと飽きずに長く使えるもの（本当に自分の欲しいものか）を調べさせました。
どこまでググる事に慣れたかは微妙ですが、なんとなく調べる事まではできたようです。
ブックマークさせる事も覚えさせました。

#functionを教えてみる
HTMLとJavascriptのおさらいをしつつfunctionの説明をしました。
functionは機能であること。今はまっている戦車ゲームになぞって説明しました。
戦車ゲームにある機能は
・作る
・打つ
・戦う
などです。「作る」とか「打つ」という機能をプログラムする事をfunctionを作るという説明をしてみました。
じゃんけんゲームにおきかえて、まずは「自分がえらんだ手を表示させる」というfunctionを作ってみせました。

```javascript:index.html

function select(data){
 alert(data);
}
//中略
<button onclick="select('パー');">パー</button>
```
この結果を出力させるとテンションがあがってました。
まだまだ楽しく感じているようで一安心です。

<img width="1259" alt="スクリーンショット 0001-07-16 23.11.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/0bd3a494-4232-54e5-c4fc-8ad686ffa7d5.png">


[今日までの成果](https://github.com/fu-jimoto/MySon-s-Program/commit/61ad64d0f594995b062d9c8c4175172a7c98213a)

又、復習として今日までやったことを嫁に説明させました。それを受けて嫁の一言。
「ママがcssで装飾しようかなー」
だそうです。

次はコンピューターが何を出すか決めさせる処理に入っていきます。


#ランダムについて教えてみる
コンピューターが「ぐー」「ちょき」「ぱー」を選ぶにはやはり乱数です。
乱数のコードを小２に理解させるのは厳しそうなので以下のサンプルをまず用意してあげました。

```javascript

var items = ['りんご','みかん','すいか','もも'];
var random = Math.floor( Math.random() * items.length );
```

このitemsという箱の中から何か適当に一個だけ選ぶんだよととりあえず教えました。
これをもとに「ぐー」「ちょき」「ぱー」を選ぶように書かせました。

```javascript

var items = ['ぐー','ちょき','パー'];
var random = Math.floor( Math.random() * items.length );
```
今日はひとまずここまで。
第16回VR技術者認定試験（セオリーコース）解答予想

今回は[Nakajiさん](https://twitter.com/nkjzm)が受験なされていらっしゃいませんでしたので私がやりました。
間違いありましたら、編集リクエストください。

|問題番号|　|　| 解答 |
|---|---|---|---|
|第1問|(a)|1|ア|
|　　 |　|2|イ|
|    |(b)|3|エ|
|　　 |   |4|ア|
|　　 |(c)|5|ウ|
|　　 |   |6|ウ|
|　　 |(d)|7|ア|
|第2問|(a)|8|オ|
|　　 |  |9|ア|
|　　 |(b)|10|ア|
|　　 |  |11|エ|
|　　 |  |12|ウ|
|    |(c)|13|イ|
|　　 |(d)|14|イ|
|第3問|(a)|15|ウ|
|　　 |(b)|16|ウ|
|　　 |(c)|17|イ|
|     |(d)|18|イ|
|　　 |   |19|エ|
|　　 |(e)|20|イ|
|第4問|(a)|21|イ|
|　　 |  |22|ア|
|     |  |23|イ|
|　　 |(b)|24|ウ|
|第5問|(a)|25|エ|
|    |(b)|26|ア|
|　　 |(c)|27|オ|
|　　 |   |28|イ|
|　　 |   |29|イ|
|　　 |(d)|30|ア|
|    |   |31|イ|
|第6問|(a)|32|オ|
|　　 |(b)|33|エ|
|　　 |(c)|34|エ|
|     |  |35|ウ|
|　　 |(d)|36|ウ|
|第7問|(a)|37|イ|
|     |(b)|38|ウ|
|　　  |(c)|39|ア|
|　　  |   |40|ウ|
|第8問|(a)|41|オ|
|　　  |(b)|42|ウ|
|　　  |   |43|ア|
|　　  |(c)|44|ア|
|第9問 |(a)|45|オ|
|    　|   |46|ア|
|　　  |(b)|47|オ|
|     |   |48|イ|
|　　  |   |49|オ|
|第10問|(a)|50|ウ|
|      |   |51|イ|
|　　  |   |52|イ|
|　　  |   |53|ア|
|     |(b)|54|イ|
|　　  |　　|55|ウ|
|　　　|   |56|イ|
|第11問|(a)|57|ア|
|　　  |   |58|ウ|
|　　  |(b)|59|イ|
|　　  |　　|60|イ|
|　　  |　　|61|オ|
|第12問|(a)|62|エ|
|　　  |　　|63|ウ|
|　　  |(b)|64|ア|
|　　  |   |65|オ|
|　　  |   |66|エ|
|第13問|(a)|67|オ|
|　　  |(b)|68|オ|
|第14問|   |69|オ|
|　　  |   |70|ア|
|　　  |   |71|ウ|
|　　  |   |72|ウ|
|　　  |   |73|オ|
|第15問|(a)|74|イ|
|　　  |(b)|75|イ|
|　　  |(c)|76|イ|
|     |  |77|オ|
|　　  |(d)|78|オ|
|第16問|(a)|79|ア|
|     |   |80|ア|
|　　  |(b)|81|イ|
|　　  |(c)|82|イ|
|第17問|(a)|83|ウ|
|　　  |  |84|イ|
|　　  |(b)|85|ウ|
|　　  |  |86|エ|
【Ruby】小数点以下の桁数を指定して四捨五入、切り上げ、切り捨て！

#はじめに
今回は、少数の桁数を指定して、四捨五入や切り上げ切り捨てを行う方法をまとめました。
平均値などを算出する際に、どうしても少数になってしまう場合は多いです。
そんな時に小数点以下の桁数を統一する必要性が出てきます。
では早速説明に入ります:cop:

#小数点以下N桁で四捨五入
###roundメソッド

roundメソッドは、引数に小数点以下の桁数を入力することにより、それより下の桁を四捨五入してくれます。
小数点以下２桁までを表示させたい場合は`round(2)`
小数点以下3桁までを表示させたい場合は`round(3)`
以下が例です。

```console
100.3333.round
# 出力結果 ==> 100

100.3333.round(1)
# 出力結果 ==> 100.3

100.3383.round(2)
# 出力結果 ==> 100.34

100.3399.round(3)
# 出力結果 ==> 100.34
# この場合、小数点以下４桁目が四捨五入されるが３桁目の元の値が9なのでさらに繰り上がって100.34になる。

```
#小数点以下N桁で切り上げ
###ceilメソッド
こちらもroundメソッドと同様、引数で桁数を指定してあげてください！
以下が例です。

```console
100.3333.ceil
# 出力結果 ==> 101

100.3333.ceil(1)
# 出力結果 ==> 100.4

100.3383.ceil(3)
# 出力結果 ==> 100.339

100.3399.ceil(3)
# 出力結果 ==> 100.34
```

#小数点以下N桁で切り捨て
###floorメソッド
こちらもroundメソッドと同様引数で桁数を指定してあげてください！
以下が例です。

```console
100.3333.floor
# 出力結果 ==> 100

100.3333.floor(1)
# 出力結果 ==> 100.3

100.3383.floor(3)
# 出力結果 ==> 100.338

```

#さいごに
以上です！とても簡単ですね。
四捨五入するのか、切り上げもしくは切り捨てるのかは、プロジェクトによっても様々だと思います。
くれぐれも間違えて使用しないようにだけ気をつけてください！
小銭計算プログラムの写経のメモ

```index.html
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<link rel="stylesheet" href="style.css">
<body>
  <div id="app" class="container"> <!--vueの宣言-->
    <div class="row">
      <div class="col-8 offset-2">
        <h1 mt-5 >小銭の計算</h1>
        <div>
          <p>いくら</p>
          <p><input type="number" name="price" v-model=price><button @click="calc()">計算</button></p>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-4 offset-2">
        500円 :{{yen500}}
      </div>
      <div class="col-4">
        100円  :{{yen100}}
      </div>
      <div class="col-4 offset-2">
          50円 :{{yen50}}
        </div>
        <div class="col-4">
          10円 : {{yen10}}
        </div> <div class="col-4 offset-2">
            5円 : {{yen5}}
          </div>
          <div class="col-4">
            1円 :{{yen1}}
          </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js">
```


```main.js
var app=new Vue({
  el:'#app',
  data:{
     price:0,　//input要素の指定
      yen500:0,
      yen100:0,
      yen50:0,　//gridの指定
      yen10:0,
      yen1:0,
  },
  methods:{　
    calc:function(event){　　//buttonをクリックしたときの処理を宣言
      change=this.price;　//changeはその関数内でしか適用されない
  this.yen500=Math.floor(change/500);//500でわった切り捨ての値を代入
      change %=500;　その値をchangeに代入
 this.yen100=Math.floor(change/100);//500で割り切れなっかたあまりを
//100で割る
change %100;
      this.yen50=Math.floor(change/50);
      change %=50;
      this.yen10=Math.floor(change/10);
      change %=10
      this.yen5=Math.floor(change/5);
      this.yen1=change % 5; //5で割り切れなった余りが全部1円になる。
    }
  }
})
</script>

```

[【5分で作る】Vue.js+Bootstrapで小銭計算プログラムを作ろう](https://www.youtube.com/watch?v=Tu5NXCoiQfE&t=385s)
ユーザー登録画面を作成しながらDBを操作する画面作成の基礎を勉強してみる～コントローラとルーティングの作成～


 1. コントローラを作成します
 2. ルーティングを設定します

## 1. コントローラを作成します

コントローラーを作成して、編集します。

```
$ php artisan make:controller UserController
```
```php:app/Http/Controllers/UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    // 一覧表示
    public function index(Request $request)
    {
      return "index";
    }
    // 追加ページ表示
    public function create(Request $request)
    {
      return "create";
    }
    // 追加処理
    public function store(Request $request)
    {
      return "store";
    }
    // 参照ページ表示
    public function show(Request $request)
    {
      return "show";
    }
    // 編集ページ表示
    public function edit(Request $request)
    {
      return "edit";
    }
    // 編集処理
    public function update(Request $request)
    {
      return "update";
    }
    // 削除処理
    public function destroy(Request $request)
    {
      return "destroy";
    }
}
```

## 2. ルーティングを設定します

ルーティングを追加します。

```php:routes/web.php
Route::get('/users', 'UserController@index');
Route::get('/users/create', 'UserController@create');
Route::post('/users', 'UserController@store');
Route::get('/users/{id}', 'UserController@show');
Route::get('/users/{id}/edit', 'UserController@edit');
Route::put('/users/{id}', 'UserController@update');
Route::delete('/users/{id}', 'UserController@destroy');
```

## 動作確認

テスト用の画面を用意してルーティングが正しく設定されているか確認します。
ルーティングの設定をします。

```php:routes/web.php
Route::get('test', function() {
  return view('users.test');
});
```

画面を作成します。
`@csrf` ... LaravelではCSRF対策がされているのでフォームを送信する時は、`@csrf`を記述します。
`@method` ... htmlからはGETとPOSTのリクエストしか投げられないため、PUTやDELETEを使う場合は「疑似メソッド」を使用します。`@method(メソッド名)`の形式で指定します。

```html:resources/view/users/test.blade.php
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <a href="/users">index</a>
    <a href="/users/create">create</a>
    <form method="post" action="/users">
      @csrf
      <input type="submit" value="store">
    </form>
    <a href="/users/100">show</a>
    <a href="/users/100/edit">edit</a>
    <form method="post" action="/users/100">
      @csrf
      @method('PUT')
      <input type="submit" value="update">
    </form>
    <form method="post" action="/users/100">
      @csrf
      @method('DELETE')
      <input type="submit" value="delete">
    </form>
  </body>
</html>
```

テスト画面を表示して、各リンクやボタンをクリックして正しい文字列が返ってくればOKです。

## 参考
railsでsns認証 fb google client_id error

1
```
config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'] ,ENV['GOOGLE_CLIENT_SECRET']
```

ここの設定でつまづいた。

https://stackoverflow.com/questions/34810776/google-authentication-error-invalid-request-missing-required-parameter-client
まさしくこんな感じのclient_idがないと怒られました。

３時間ほど彷徨いましたが解決策は非常にシンプルでした。
2
```
config.omniauth :google_oauth2,ENV['GOOGLE_CLIENT_ID'],ENV['GOOGLE_CLIENT_SECRET']
```
以上の設定をしているとエラーが起きました。
わかりますか？？
2の方はspaceが空いていないのが！！！！

このspaceがclient_idの読み込みを邪魔していたみたいです・・・・・。

変更した後に、serverを立ち上げ直すことを忘れないように。
また、環境変数はbashに書いていたのですが、どうもうまくいかなかったので.envのgemを用いて、そこに設定しました。git ignoreするのを忘れないように。
react-infinite-scroll-componentでうまくスクロールできないときの対処法

Reactで無限スクロールを実現するものに`react-infinite-scroll-component`というシンプルなコンポーネントがあります。
Github: [ankeetmaini/react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component)

とてもシンプルで使いやすいのですが、

* 親要素の高さが十分でないと機能しない
* `<InfiniteScroll>`のなかにコンテンツ以外の枠などが含まれているとうまく動作しない

などのデメリットもあります。

そして今日ぶつかったバグは、画像のようにiOSのSafariにおいてうまくスクロールできない症状です。
![infinite-scroll.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/fc7f1ece-9c0b-eab5-f13a-d937d5aae862.gif)
ちょっと分かりづらいですが、最初のタッチで引っかかる感じです。

##解決した方法
以下のスクリプトをhtmlに追加しました。

```html
<script>
	document.addEventListener("DOMContentLoaded", function(event) {
	   document.querySelector('.infinite-scroll-component ').removeAttribute('style')
	});
</script>
```
問題は、クラス`infinite-scroll-component `が`-webkit-overflow-scrolling: touch;`というスタイルを持っているから起きているようでした。なので、style属性丸ごと削除しています。

githubにissue投げろよという感じですが、とりあえず自分用のメモと、同じバグで悩む日本人を救えればという思いです。
【初心者向け】チェックボックスの書き方あれこれ[Ruby][Rails]

やはりフォームの作成方法が難しいたぬきです。今回は、collection_check_boxというviewヘルパーの理解にかなり時間がかかったので、備忘も兼ねて整理してみようと思います。

# check boxの書き方３つ
そもそも、チェックボックスの書き方なのですが、以下の３つの方法があり、それぞれ以下のように使い分けます。

- check_box_tag（関連するモデルがないとき）
- check_boxメソッド(関連するモデルがあるとき)
- collection_check_boxes(多対多のリレーションのモデルを表現するときに便利）

## check_box_tagの書き方
check_box_tagの書き方は以下の通りです。一緒に、ラベルも併記しています。
なお、以下、viewの情報はhamlで書きます。

```ruby
= check_box_tag :check1
= label_tag :check1, "ラベルのテスト"
```
実行結果は以下の通り。

[![Image from Gyazo](https://i.gyazo.com/685020599cde18b93b9174884f0c0562.png)](https://gyazo.com/685020599cde18b93b9174884f0c0562)

一つのチェックボックスができました。

## check_box の書き方
check_boxの書き方は以下の通りです。

```ruby
= check_box :group, :user_ids, {class: "check_box"}, true, false
```

リファレンスによると、

```
check_box(オブジェクト名, プロパティ名 [, オプション, checked_value = "1", unchecked_value = "0"])
```
という構造になっているようで

- 第１引数（オブジェクト名）・・・データを保存したいモデル名
- 第２引数（プロパティ名）・・・データを保存したいカラム名
- 第３引数（オプション）・・・クラス名など。色々入ります。（<a href="http://railsdoc.com/references/check_box" target="_blank">詳しくはこちら</a>）
- 第4引数、第5引数・・・チェックが入っている時のvalue値を1にするか否か、チェックが入っていない時のvalueを0にするか否かの設定です。`true`や`false`にもできます。

ちなみに、check_boxではなく、f.check_boxの形にすると（つまり、form_withやform_forの中で使うと、第１引数（オブジェクト）が省略できるようです。

form_withやform_forの中で、関連するモデルは定義していますものね。。。

## collection_check_box　の書き方
最後に、collection_check_boxを用いたチェックボックスの書き方です。`collection`(Railsではインスタンスの集まり)のデータを利用して、（一つ一つ定義しなくても）一気にチェックボックスを作ってしまえる便利メソッドです。

こちらは多対多のリレーション構造の中でチェックボックスを利用するときに便利な書き方、という形で紹介されることが多いのですが、、、

書き方は、こんな感じ

```ruby
= collection_check_boxes :group, :user_ids, User.all, :id, :name do |user|
  = user.label { user.check_box + user.text }
```

書かれている内容の詳細な解説はこちらのページが詳しいです。
▼collection_check_boxesメソッドの構造確認
https://qiita.com/sho012b/items/3a595fde14516081dff5

▼railsで多対多な関係を実装する時のポイント
https://qiita.com/m-shin/items/0487105994d9281221d4

構造的には、このような形になっていて

```
collection_check_boxes(object, method, collection, value_method, text_method)
```

それぞれ、引数は以下のような意味を持ちます。

- 第１引数：データを保存するテーブル
- 第２引数：データを保存するカラム
- 第３引数：ここで指定して持ってきているデータ（配列）の数だけ、チェックボックスが作成される
- 第4引数：生成されるinputタグのvaule属性の値（下記参照）
- 第5引数：生成されるinputタグのテキストとなる値（下記参照）

生成されたHTMLタグはこちら

```html
<input type="checkbox" value="1" name="group[user_ids][]" id="group_user_ids_1">"ここに生成されたテキストが入ります"
```
check_boxと同様に、<strong>form_with</strong>などの中で<strong>f.collection_check_boxes</strong>のような形で使うときには、第１引数が省略できます！

最後に、こちら２行目の部分ですが、

```ruby
= collection_check_boxes :group, :user_ids, User.all, :id, :name do |user|
  = user.label { user.check_box + user.text }
```
<a href="https://apidock.com/rails/v5.0.0.1/ActionView/Helpers/FormOptionsHelper/collection_check_boxes" target="_blank">Apiドキュメント</a>によると、ラベルを生成するためのオプションだそうです。

（上記ドキュメントの下方に「The builder methods label and check_box also accept extra HTML options:」という記述があるので、そちらをみてください）

特に、check_boxの理解とcollection_check_boxの第２引数の理解が甘いですが、２ヶ月ほど前にはお手上げだったカリキュラムも何とか噛み砕いて理解できるようになりました。。。

ちなみに、なぜ多対多の関係で便利かと言うと、`:user_ids`の指定で、中間テーブルに必要なデータ（ここでは第４引数で指定しているユーザーの`:id`）をドバッと一気に送れるからなのですね〜

formは特別な書き方が多く本当に難しいですね。いつかform周りで得た知識をまとめてみたいです。引き続き精進いたします。

### その他
2020年8月、編集リクエストが届いていることに気づき、マージするとともに、当時理解が曖昧だった内容を加筆修正しました。