OmniAICreator/Qiita-1.07M huggingface dataset:
Railsのお気に入り機能(Ajax)をjQueryから素のJavaScriptに置き換える

Railsによる個人サービス [supplebox.tokyo](https://supplebox.tokyo/) ではお気に入りの追加・削除機能をAjaxを利用して実現しています。

この非同期用のJavaScript用の埋め込みRuby（.js.erb）ファイルでは、jQueryを使っていました。
jQueryを利用しているのは、Rails Tutorialを始め、私の周りの学習教材ではjQueryが利用されていたためでした。

しかし、ここ最近しっかりとJavaScriptを学習しはじめると、わざわざjQuery使わなくても素のJavaScript(Vanila JS)でもできるんじゃないの?と思いたち、実際にできたため、書き方を記事にまとめます。

なお、本記事では`.js.erb`ファイルのみに焦点を当てているため、Ajaxを使った機能自体の詳細については、 [Rails Tutorial](https://railstutorial.jp/chapters/following_users?version=6.0#sec-a_working_follow_button_with_ajax)や参考記事をご参考ください。

## 修正前
修正前も修正後も`app/views/likes/create.js.erb`と`app/views/likes/destroy.js.erb`の記述内容は同一なので、`app/views/likes/create.js.erb`についてのみ言及します。

```app/views/likes/create.js.erb
var product_id = <%= @product.id %> 
$(`#product-${product_id}`).html("<%= escape_javascript(render('likes/like_small_button', product: @product)) %>")
```

このファイルでやっていることを端的にまとめます。

- ステップ1. `product_id` に `@product.id`を代入する
-  ステップ2. `#product-${product_id}`の要素を取得している
-  ステップ3. ステップ2で取得した要素の中身を`<%= escape_javascript(render('likes/like_small_button', product: @product)) %>`に置き換える

もう少し細かく分解してみると、下記と同じことになります。

```app/views/likes/create.js.erb
var product_id = <%= @product.id %> // ステップ1
var element = $(`#product-${product_id}`) // ステップ2
element.html("<%= escape_javascript(render('likes/like_small_button', product: @product)) %>") // ステップ3
```

参考

- [jQuery](https://jquery.com/)


## 修正後
修正前のステップ1~3を素のJavaScriptに置き換えていきます。

```app/views/likes/create.js.erb
var product_id = <%= @product.id %> // ステップ1(ここは変更なし)
var element = document.getElementById(`product-${product_id}`)
 // ステップ2
element.innerHTML = "<%= escape_javascript(render('likes/like_small_button', product: @product)) %>" // ステップ3
```

以上で完了です。

もちろん、メソッドチェーンを使って下記のように書くこともできます。

```app/views/likes/create.js.erb
document.getElementById("product-<%= @product.id %>").innerHTML = "<%= escape_javascript(render('likes/like_small_button', product: @product)) %>"
```

参考

- [Document.getElementById() - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document/getElementById)
- [element.innerHTML - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Element/innerHTML)
- [【Rails】いいね機能完全版！同期いいね、いいね数の表示、非同期いいね、アイコン表示、それぞれの実装方法についてまとめて解説｜TechTechMedia](https://techtechmedia.com/favorite-function-rails)
AWS CLI install in Ubuntu 20.04

# はじめに

Ubuntu 20.04 に AWS CLI を導入する手順を備忘録としてメモです。



# EC2の準備

適当に Ubuntu 20.04 を作成して、SSH 接続します



# AWS CLI の Install

作業用ディレクトリ作成

```
mkdir ~/temp
cd ~/temp
```



AWS CLI Install

```
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```



# AWS CLI の 設定

AWS IAM で Access Key ID と Secret Access Key を生成して、aws configure コマンドで設定します

region : ap-northeast-1

```
aws configure
```



# Fish 補完の設定

自分の環境では、bash ではなく fish を使っています。fish の AWS CLI 用補完設定をします

```
vim ~/.config/fish/completions/aws.fish
```



ファイルの中身

```
complete -c aws -f -a '(
    begin
        set -lx COMP_SHELL fish
        set -lx COMP_LINE (commandline)
        aws_completer
    end
)'
```



# 動作確認

EC2 の一覧

```
aws ec2 describe-instances --query "Reservations[].Instances[].Tags[?Key==`Name`].Value[]"
```



実行例

```
> aws ec2 describe-instances --query "Reservations[].Instances[].Tags[?Key==`Name`].Value[]"
[
    "StepBox"
]
```



# 参考URL

Document
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html
SQLインジェクション

## 1. SQLインジェクション
データベースへの悪意あるリクエストにより、データベースの不正利用をまねくような脆弱性。

### 根本的解決その1: SQL文の組み立ては全てプレースホルダで実装する
下記はRailsアプリの検索フォーム用searchアクションです。Postモデルから指定文字列を含む投稿の配列を取得します。

```posts_controller.rb

def search

  @posts = if params[:search].present?
             Post.where([
               'カラム名 LIKE ?', "%#{params[:search]}%"
             ])
           else
             Post.none
           end

# ダメなSQL → 'カラム名 LIKE "%#{params[:search]}%"'

end
```
?というSQLプレースホルダを用いて、まずSQL構文を決定した後に実際の値を機械的な処理で割り当てるというもの。
（※プレースホルダ・・・実際の内容を後から挿入するために、とりあえず仮に確保した場所のこと。）
直接、文字列連結処理によってSQL構文を組み立てる方法に比べて、このように機械的な処理でSQL構文を組み立てる方法を取ることでSQLインジェクションの脆弱性を解消できるとのこと。

## 参考文献
[IPA - 安全なウェブサイトの作り方](https://www.ipa.go.jp/security/vuln/websecurity.html#sql)
[Python] [Folium]海外の日本人サッカー選手を地図上で可視化する　2021.1.1現在

Japanese football players in foreign clubs shown on the map.

##この記事について

現在、ビジャレアルの久保選手の動向が話題になっているところですが、海外で活躍されてる選手はどこにいるのかPython/Foliumで可視化してみました。その中で工夫したポイントを説明したいと思います。

１．Foliumでアイコンを所属チームのマークにした
２．所属選手名をクリックではなく、マウスオーバーで表示させるようにする
３．データの入手・前処理について

##結果
[完成したものはこちらからアクセスしてください](https://kent747tak.github.io/J-FootballPlayersAbroad/)
![Videotogif(3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/953441f7-babf-e4be-edc4-778124cbeda5.gif)


## チームのアイコン表示について

カスタムアイコンはfolium.features.CustomIconを利用しました。
なかなか日本語の説明もなく、[英語のFoliumのサイトの説明](https://python-visualization.github.io/folium/modules.html)を頼りになんとなくやっていたらできました。

チームのアイコンはネットで収集したものを、背景透明にしてpngで、imageフォルダに入れてあり、アイコンが見つからない場合のエラー処理も以下のコードには入れてあります。

##所属選手名をクリックではなく、マウスオーバーで表示させるようにする
このマウスオーバーで情報を表示することを、英語でtooltipというそうです。
それをFoliumのmarkerを指定するときに
tooltip='文字列'
で指定するだけです。以下のコードを参考にしてください。

##　データの入手・前処理について
まずはWikipediaの情報をもとに、ホームタウン、ホームスタジアムの経度・緯度、アイコンなどをかき集めてエクセルにしています。
本当は自動でスクレイピングでやりたかったのですが、それほど数もないので手動にしました。。。
集めた各選手・チームのデータはEXCELで保存し、Pandas/Dataframeからプロットしています。

エクセルデータはこちらの薄い水色の列だけ利用
![スクリーンショット 2021-01-04 103045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/d8ab9f5f-c54a-1474-8110-bf7a149bc424.png)

それなりにデータを集めるのは大変でした　汗

##コード

```python

import pandas as pd
import folium
from glob import glob

df_player= pd.read_excel ('PlayerClubData.xlsx', header=0,encoding='utf-8' )

m = folium.Map(location=[46, -1.5],  zoom_start=4)

for club in df_player['club'].unique():
    df2=df_player[df_player['club']==club]  #２名以上いる場合、名前を結合する
    names=' '.join(df2['Player'].tolist()) # Series = > List => joinしてstr

    for item in df2.head(1).iterrows():  #ちょっとややこしいが、各クラブの１人目だけプロットするのでhead(1)

        if item[1]['lat']>0 or item[1]['lat']<0 :  # 経度データがfloatでnanはスキップする
            l_in = [s for s in glob("./images/*.png") if club in s]  #アイコンファイルがあるかチェックする
            if len(l_in)>0: #該当するファイル数　通常は1
                iconTmp = folium.features.CustomIcon(l_in[0], icon_size=(50,50)) #ここでアイコンファイルを指定する 
            else:
                iconTmp=folium.Icon(color='red') #アイコンファイルがない場合はこちら

            folium.Marker(location=[item[1]['lat'], item[1]['lon']], 
                tooltip=item[1]['club']+'<br>'+names,   #　このtooltipでマウスオーバーで表示できる
                icon=iconTmp).add_to(m) #上で指定したアイコンファイルにする
            
m.save('index.html')

print ('finished!')
```
[ソースコード及びデータファイルはこちらから]
(https://github.com/Kent747Tak/J-FootballPlayersAbroad)

##　参考

[Foliumでアイコンを表示するサンプル（英語）Python Folium — A Data Visualization Superhero](https://medium.com/python-point/a-data-visualization-superhero-python-folium-73fe1a0a0c48)
サンプルコードが分かりやすかったです。

[サッカー海外組の所属クラブ - 全画面地図 ]
(https://map.ultra-zone.net/japanese_player)
始めはこちらをみて、同じものを作りたいと思いました。このメンバーは2012年？！

[Pythonのfoliumで岩手県内の病院の場所を可視化してみる](https://qiita.com/kihei171/items/b3d9dad5da7d7b52c4dd)
こちらもいろいろと参考にさせていただきました。


##感想
covid-19で海外に気軽に行けなくなってしまいましたが、個人的には海外旅行は観光スポットを巡るるのもいいのですが、現地でサッカー観戦するのも楽しいかと思います。その際にはこの地図で効率よく観戦できるルートを検討していただければと思います。

＃個人的には、久保建英、南野拓実、スウェーデンにいる杉田祐希也 、宮市亮に期待しています！
Unity2020(2020.1.2.f1)で発生するJSON parse errorについて

#概要
Unityで新規に作成したプロジェクト内で、以下のようなエラーが出ることがないでしょうか。

```
Error detecting Visual Studio installations: System.ArgumentException: JSON parse error: Invalid escape character in string.
```

#対処法
プロジェクト内にあるPackagesの中にあるDiscovery.csを変更する必要があります。
私のバージョンの場合は
「Library\PackageCache\com.unity.ide.visualstudio@2.0.2\Editor」という配下に有りました。

変更する内容は
IEnumerableクラス内にあります、以下のように変更します。

```
var process = new Process
			{
				StartInfo = new ProcessStartInfo
				{
					FileName = progpath,
					/*
					 * 変更前
					 * Arguments = "-prerelease -format json",
					 */
					Arguments = "-prerelease -format json -utf8",
					UseShellExecute = false,
					CreateNoWindow = true,
					RedirectStandardOutput = true,
					RedirectStandardError = true,
				}
			};
```

変更後は再起動をする必要があります。
また、新規で別のプロジェクトを作成するたびに出てきてしまうため、その都度対処が必要になります。


#参考URL
https://www.codelab.jp/blog/?p=1827
【C言語】関数ポインタの基礎

この記事では，関数ポインタの基礎的な使い方について解説したいと思います．

##関数もアドレスを持っている##
関数も変数と同じようにメモリ領域に保存されているので，アドレスを持っています．
まずは，そのことを確かめてみます．

```c
#include <stdio.h>

int main(void){
    printf("%p\n", main);
    return 0;
}
```
```:実行結果
0x563c3dc4c64a 
```
実行結果は環境によって異なりますが，関数名が関数のアドレスを表していることがわかりました．

##関数ポインタの宣言##
関数ポインタは以下のように宣言することが出来ます．

```
戻り値の型 (*ポインタ変数名)(引数情報);
```
これだけではよくわからないと思うので，例を見てみましょう．
例えば，２つの整数の内，大きい方の整数を返す関数`int max(int, int);`を保持するポインタ`p_func` の宣言をしてみます．

```c
int (*p_func)(int, int);
```

##関数ポインタの使い方##
まず，関数ポインタへ関数のアドレスを代入します．最初に確認したように，関数名が関数のアドレスを表しているので以下のように代入を行えます．

```c 
p_func = max;  //ポインタ変数名 = 関数名
```

次に，関数の呼び出しです．

```c
(*p_func)(3, 5);
```

関数ポインタを間接参照することによって，`p_func`に代入されている関数`max`を呼び出すことができます．
もっと簡単に呼び出すこともできます．

```c
p_func(3, 5);
```

1つめの呼び出し方の方がポインタを使っている感じはしますが，こちらの方が簡単でいいですね．


##まとめ##
ここまでに説明したものをまとめたものが以下のプログラムになります．

```c
#include <stdio.h>

int max(int a, int b){
    int max = a;

    if (max < b)
        max = b;
    return max;
}

int main(void){
    int (*p_func)(int, int);

    p_func = max;
    printf("(1)(*p_func)(3, 5) = %d\n", (*p_func)(3, 5));  //(1)
    printf("(2)p_func(3, 5) = %d\n", p_func(3, 5));        //(2)
}
```

```:実行結果
(1)(*p_func)(3, 5) = 5
(2)p_func(3, 5) = 5
```

##おまけ（関数ポインタと配列）##
関数ポインタは配列と組み合わせて使用されることが多いです．if文やswitch文などの処理分岐をする必要がなくなり，簡潔にプログラムを書けるようになることがあるからです．
以下のようにすると，関数ポインタの配列を宣言できます．

```
戻り値の型 (*ポインタ変数名[配列の要素数])(引数情報);
```

先ほどの例で言うと，次のようにします．

```c
int (*p_func[2])(int, int);
```

同じ戻り値の型，引数の関数しか格納できませんが，それぞれの要素に関数のアドレスを格納して使います．
最後に例を示しておきます．

```c
#include <stdio.h>

int max(int a, int b){
    int max = a;

    if (max < b)
        max = b;
    return max;
}

int min(int a, int b){
    int min = a;

    if (min > b)
        min = b;
    return min;
}

int main(void){
    int (*p_func[2])(int, int);

    p_func[0] = max;
    p_func[1] = min;
    for (int i = 0; i < 2; i++)
        printf("p_func[%d](3, 5) = %d\n", i, p_func[i](3, 5));
}
```

```c:実行結果
p_func[0](3, 5) = 5  //maxが呼び出されている
p_func[1](3, 5) = 3  //minが呼び出されている
```
BoundFieldクラス

#BoundFieldクラスとは
GridViewコントロールは，フィールドの表示，編集を行います。詳細にカスタマイズするためクラスが用意されており，BoundFieldクラスは，文字列を出力するときに使用し，数値や日付などの書式設定が可能です。

#例
```html:GridViewSample.aspx
<asp:BoundField DataField="Birthday" HeaderText="誕生日" DataFormatString="{0:yyyy/MM/dd}" />
<asp:BoundField DataField="Sales" HeaderText="当期売上高" DataFormatString="{0:C}" />
```

#使い方
1. デザイン画面で「>」ボタンを押下します。
![grid.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700136/41bfe29b-e545-c304-1c7a-8fff646aa931.png)

2. 「誕生日」を選択し，「DataFormatString」を「{0:yyyy/MM/dd}」に設定します。
![grid2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700136/cf771ff9-dccd-7bde-7739-96e8d7c7267e.png)

3. 「金額」を選択し，「DataFormatString」を「{0:C}」に設定し，「OK」ボタンを押下します。
![grid3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700136/db25adb7-6067-1a17-eb86-f430fe39c967.png)

4. 「誕生日」は年月日のみ，「金額」は通貨として出力されます。
![grid4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700136/56ab8f76-0686-6d93-f440-798ac4bf37ae.png)

#書式指定文字列
以下のような書式指定文字列があります。

|指定例|書式指定文字列|表示結果|
|---|---|---|
|通貨表示|{0:C}|￥12,000,000|
|0埋め数値表示|{0:000,000,000}|012,000,000|
|指数表示|{0:e}|1.200000e+007|
|曜日付き年月日指定|{0:yyyy/MM/dd dddd}|1975/02/03 月曜日|
|日付，時間指定|{0:yyyy/MM/dd HHmmss}|1978/10/25 230312|
|時間指定（12時間表記）|{0:tt hhmmss}|午後 110312|


#プロパティ
その他，以下のようなプロパティがあります。

|プロパティ|意味|
|---|---|
|DataField|出力するフィールド名|
|DataFormatString|出力の際の書式指定文字列を指定|
|ApplyFormatlnEditMode|編集時にDataFormatStringプロパティの書式設定を適用するかどうか|
|ConvertEmptyStringToNull|空文字列をnullに自動変換するか|
|HtmlEncode|出力する文字列をHtmlエンコードするかどうか|
|NullDisplayText|フィールドの値がnullの場合に表示する文字列|
|ReadOnly|編集時に値を編集不可にするかどうか|

##参考文献
TECHNICAL MASTER はじめてのASP.NET Webフォームアプリ開発 VisualBasic対応 第２版
開発環境(Docker)のPHPのバージョンを7.2.11から7.4.xにアップデートした時にハマったこと

開発環境のPHPのバージョンを7.2.11から7.4.xにアップデートするために、既存のDockerfileを編集することになった。

## 実現したかったこと
開発環境(Docker)のPHPのバージョンを7.2.11から7.4.xにアップデートする。

```dockerfile

# Dockerfile

# ↓これを7.4.xにしたい
FROM php:7.2.11-apache 

RUN apt-get update \
&& apt-get install -y zlib1g-dev \
&& docker-php-ext-install zip \
&& apt-get install -y unzip
```

## 結論
最終的にはこの形になった。

```dockerfile
# Dockerfile

FROM php:7.4.13-apache

RUN apt-get update \
&& apt-get install -y zlib1g-dev \
&& apt-get install -y libzip-dev \
&& docker-php-ext-install zip \
&& apt-get install -y unzip
```

## やったこと

[DockerHub](https://hub.docker.com/_/php)を見ると、`7.4.13-apache`というイメージがあったので、とりあえず変えてみた。

```dockerfile

# Dockerfile

# ↓7.4.13に変えた
FROM php:7.4.13-apache

RUN apt-get update \
&& apt-get install -y zlib1g-dev \
&& docker-php-ext-install zip \
&& apt-get install -y unzip
```

しかし。。。

```console
$ docker-compose build
...
略
...
configure: error: Package requirements (libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0) were not met:

No package 'libzip' found
No package 'libzip' found
No package 'libzip' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables LIBZIP_CFLAGS
and LIBZIP_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
ERROR: Service 'service_name' failed to build : The command '/bin/sh -c apt-get update && apt-get install -y zlib1g-dev && docker-php-ext-install zip && apt-get install -y unzip' returned a non-zero code: 1
```

`libzip`とかいうやつが無いらしい…
なので、`apt-get install libzip-dev`を追加した。

```dockerfile
FROM php:7.4.13-apache

# zlib zip unzip
RUN apt-get update \
&& apt-get install -y zlib1g-dev \
&& apt-get install libzip-dev \
&& docker-php-ext-install zip \
&& apt-get install -y unzip
```

すると…

```
$ docker-compose build
...
略
...
The following package was automatically installed and is no longer required:
  sensible-utils
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
  libzip4
The following NEW packages will be installed:
  libzip-dev libzip4
0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded.
Need to get 209 kB of archives.
After this operation, 436 kB of additional disk space will be used.
Do you want to continue? [Y/n] Abort.
```
`-y`オプションがないということかな？
というわけで、

```dockerfile
# Dockerfile

FROM php:7.4.13-apache

RUN apt-get update \
&& apt-get install -y zlib1g-dev \
&& apt-get install -y libzip-dev \
&& docker-php-ext-install zip \
&& apt-get install -y unzip
```

`-y`オプションを追加して再度`$ docker-compose build`を実行。

```console
$ docker-compose build
...
略
...
Successfully built ******
Successfully tagged app_name:latest
```

うまくいった！！

## 参考記事
stack oveflow
[Installing PHP-zip on a php:7.4-fpm image](https://stackoverflow.com/questions/64500293/installing-php-zip-on-a-php7-4-fpm-image)
【Ruby】小文字から大文字、大文字から小文字に変換する方法

## 概要

Railsチュートリアルで **downcase** メソッドを使用しました。使う機会が今までなかったので、今回問題を解きながら理解を深めたいと思います。関連メソッドについても簡単に見ていきたいと思います。

## 目次

- 関連メソッド

- 下記問題で使用するメソッド
    - start_with?
    - end_with?

- 実践
    - 問題
    - 解答
    - 別解

- まとめ

- 参考文献

## 関連メソッド

| メソッド | 使い方 |
|:-:|:-:|
| downcase  | 大文字を小文字に変換 |
| upcase | 小文字を大文字に変換  |
| swapcase  | 大文字を小文字に、小文字を大文字に変換  |
| capitalize  | 先頭の小文字を大文字に変換  |
|破壊的メソッド(!)| 上記のメソッドの末尾に **( ! )** を付与すると**オブジェクト**に変更を加える |

## 下記問題で使用するメソッド

#### start_with?

指定の文字列で始まっているか調べるメソッド

#### end_with?

指定の文字列で終わっているか調べるメソッド

##実践

#### 問題

>任意の2つの文字列があります。文字列同士を比べ、文字列の最後にもう一方の文字列が含まれているか確認するプログラムを書いてください。

#### 解答
小文字と大文字で区別を付けたくないので `downcase` を使用しています。`upcase` メソッドを使いすべて大文字にしても問題なく動作します。

```ruby
def end_other(a, b)

  # 小文字に変換し変数に格納
  a_down = a.downcase 
  b_down = b.downcase

  # aの文字列の中にbの文字列は入ってる? または、 bの文字列の中にaの文字列は入ってる？
  if a_down.end_with?(b_down) || b_down.end_with?(a_down)
    p 'True'
  else
    p 'False'
  end
end

# メソッド呼び出し
end_other('Apple', 'Ple')
end_other('orange', 'Range')
end_other('banana', 'Nana')
```

#### 別解
`slice` を使用することで引数で指定した箇所を切り取っています。
sliceについては[こちら](https://qiita.com/suzu12/items/95bfc11139ad76aaa236)を参考にしていただければ幸いです。

```ruby
def end_other(a, b)

  # 小文字に変換し変数に格納
  a_down = a.downcase
  b_down = b.downcase

  # 文字列の長さを取得
  a_len = a_down.length
  b_len = b_down.length

  # bの文字列からaの文字列分の文字を切り取り、aの文字列と等しい? または、 aの文字列からbの文字列分の文字を切り取り、aの文字列と等しい?
  if b_down.slice(-(a_len)..-1) == a_down || a_down.slice(-(b_len)..-1) == b_down
    p 'True'
  else
    p 'False'
  end
end

# メソッド呼び出し
end_other('Apple', 'Ple')
end_other('orange', 'Range')
end_other('banana', 'Nana')
```
## まとめ

- Rubyが用意してくれているメソッドを使うことで簡単に小文字から大文字に変換、大文字から小文字に変換などをすることができる。

## 参考文献

- [Ruby 3.0.0 リファレンスマニュアル ( downcase )](https://docs.ruby-lang.org/ja/latest/method/String/i/downcase.html)

- [Ruby 3.0.0 リファレンスマニュアル ( upcase )](https://docs.ruby-lang.org/ja/latest/method/String/i/upcase.html)

- [Ruby 3.0.0 リファレンスマニュアル ( capitalize )](https://docs.ruby-lang.org/ja/latest/method/String/i/capitalize.html)

- [Ruby 3.0.0 リファレンスマニュアル ( swapcase )](https://docs.ruby-lang.org/ja/latest/method/String/i/swapcase.html)

- [Ruby 3.0.0 リファレンスマニュアル( start_with? )](https://docs.ruby-lang.org/ja/latest/method/String/i/start_with=3f.html)

- [Ruby 3.0.0 リファレンスマニュアル ( end_with? )](https://docs.ruby-lang.org/ja/latest/method/String/i/end_with=3f.html)

- [Rubyの文字列で使えるメソッド・使い方総まとめ](https://www.sejuku.net/blog/11843)

- [sliceメソッドとは？slice!との違いを例題を解いて理解しよう！](https://qiita.com/suzu12/items/95bfc11139ad76aaa236)

- [【Ruby】sliceメソッドで要素の取り出し](https://qiita.com/suzu12/items/74db2769754d97e6ac6c)
Stripeでサブスクリプションを実装するメモ

最近個人的に、Stripeでサブスクリプションを実装する機会があったので、メモがてら流れを書いていこうと思います。

* Laravel 7.0
* Nuxt.js 2.14.6

Nuxt.jsがSPAで動いており、LaravelがAPIを返す構成になっています。

## 流れ

### 契約
1. stripeのダッシュボード上でプランを作成しておく
1. [クライアント] プランを選択してサーバーサイドへ送信
1. [サーバーサイド] 顧客情報を作成して、DBへ保存。セッションを作成してクライアントに渡す
1. [クライアント] セッションidをstripe checkout(stripeの決済用外部ページ)に渡し、支払い情報を入力させる。成功すれば`/checkout/success?session_id=XXX`などのURLにリダイレクトする
1. [クライアント] successページのqueryからセッションidを取得。サーバーサイドに渡す
2. [サーバーサイド] セッションidから顧客情報を取得、DBへ必要な情報を登録する。

### キャンセル
1. [クライアント]キャンセル情報をサーバーサイドへ送信
2. [サーバーサイド]キャンセル処理(期末で解約とする)
1. 期末で解約。stripeからwebhookでサーバーサイドのAPIを叩くことができる。DBに解約の情報を登録。有料機能の制限などを行う

ざっとこんな感じの流れです。

## stripe checkoutとelements
まず、使用を迷ったのが、この2つです。
https://stripe.com/docs/billing/subscriptions/checkout
https://stripe.com/docs/billing/subscriptions/fixed-price

これらは、決済の入力フォームを実装するコンポーネントになります。

npmはこちらを使用しました。
checkoutもelementsもこれ1つで利用できます。
https://github.com/jofftiquez/vue-stripe-checkout

checkoutとelementsの違いは、checkoutが外部のサイトで決済処理が完結するのに対して、
elementsの方がカスタマイズ性が高く、サーバーサイドの処理を必要とします。

checkoutでは、外部サイトからリダイレクトで自サイトに戻ることになるので、ユーザーIDなどを渡すのは難しそうに思っていましたが、session_idから簡単に取得できました。必要があれば、[metadata](https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-metadata)として定義することもできます。

基本的には、checkoutを選択することになるのかなと思いました。

## キャンセルの実装について
即キャンセルではなく、支払済の期末での解約にしました。
ちなみに、オプションを`'cancel_at_period_end' => true,`とすると、期末のキャンセルにできます。

```php

\Stripe\Subscription::update(
  $subscriptionId,
  [
    'cancel_at_period_end' => true,
  ]
);
```
(ちなみに即キャンセルの場合は、updateではなく、`\Stripe\Subscription::cancel`となります。)

### 解約時のwebhook
期末になり、実際の解約となるタイミングで、
stripe上で`customer.subscription.deleted`というイベントが走ります。

webhookを設定すると指定のイベントでAPIを叩くことができます。
URLは一律になるので、それをtypeでケースを分けて、処理をする形になります。

stripe cliを使うことで、localでもデバッグすることができます。
https://stripe.com/docs/stripe-cli/webhooks

```terminal
stripe listen --forward-to localhost:5000/hooks
```

これで、stripe上でイベントが流れるたびに、`localhost:5000/hooks`が叩かれることになります。

```terminal
stripe trigger payment_intent.created
```
などcli上でイベントを発生させてもいいですし、([イベント一覧](https://github.com/stripe/stripe-cli/wiki/trigger-command#supported-events))
実際にダッシュボード上や開発中のシステムでstripeのAPIを叩いた場合でも、有効です。

期末解約の実装確認では、キャンセル予定日を確認したのち、stripeのダッシュボード上で即時キャンセルして確認していました。

その他、支払い完了などのタイミングでメールの送信をシステムから行いたい場合などでも使えそうです。

## 余談: vue-stripe-checkoutのelementsで郵便番号の入力を非表示にする
https://github.com/jofftiquez/vue-stripe-checkout/issues/10
オプションがstylesしか渡せず、困ったのでイシューを探したらありました。

```nuxt.js
<template>
  <div>
    <stripe-elements
      ref="elementsRef"
      :publishableKey="publishableKey"
      :amount="amount"
      @token="tokenCreated"
      @loading="loading = $event"
      locale="ja"
    >
    </stripe-elements>
    <v-btn>送信</v-btn>
  </div>
</template>
import { StripeElements } from 'vue-stripe-checkout'
export default {
  data() {
    return {
      loading: false,
      publishableKey: process.env.STRIPE_PUBLIC_KEY,
      amount: 1000,
      token: null,
      stripeConfig: {
        hidePostalCode: true
      }
    }
  },
  mounted() {
    // configをupdateしてhidePostalCodeする
    setTimeout(
      () => this.$refs.elementsRef.card.update(this.stripeConfig),
      1000
    )
  },
}
```
herokuで、500サーバーエラーになった際の対処一例（テーブルに変更を加えていた場合）

#状況と前提条件
laravelで作成したアプリをherokuにデプロイしていたが、アプリを更新した後に開くと「500サーバーエラー」となってしまった。
※僕が遭遇したエラーの対応備忘録として記載しています。誰かの役に立てれば幸い。。。

#解決法
migrationをするのを忘れていたことに気づきmigrationする

```
$ heroku run php artisan migrate
```

ここで、以下のエラー表示され、migrationがうまくいかない。
>SQLSTATE[23502]: Not null violation: 7 ERROR:  column "user_id" contains null values (SQL: alter table "tasks" add column "user_id" bigint not null)  
※ NOT NULL なのに NULL 値が入れられようとしたためのエラーです。
　すでにテーブルに保存されていたデータが影響しています。


そのため、以下のコマンドでリフレッシュ！
（テーブルをすべて削除してマイグレーションを実行し直すコマンド）

```
$ heroku run php artisan migrate:fresh
```

無事、デプロイしたアプリが表示されます。
データはまた登録し直しましょう。。

#参考
https://qiita.com/tamappe/items/a175596e9aec725e1d2d
https://www.hypertextcandy.com/laravel-tutorial-authentication
【Node.js】開発に必要な基礎知識まとめ

## はじめに
Node.jsで開発するにあたり必要な知識について手順とともにまとめてみました。

## Node.jsについて
JavaScriptをサーバーサイドで動かす仕組みのこと

## Expressについて
- Node.jsでWebアプリの開発をするためのフレームワーク
- Webアプリケーションを作る機能を提供する

### Expressの導入方法
npmというシステムを使いインストールをする

```console
$npm install express
```

### インストールしたExpressの利用方法
jsへの記述

```javascript
// expressの読み込み
const express = require('express');
// expressを使用するための準備
const app = express();
```
## サーバーの起動について
サーバーを起動し、Webアプリを画面に表示する方法です

jsへの記述

```javascript
// アクセス可能なサーバーを起動する(ここではlocalhost:8080)
app.listen(8080);
```
jsファイルを実行する

```console
$node sample.js
```

## ページ表示の仕組み
以下の流れでページの表示を行います
ブラウザからリクエスト送信 → サーバー（Node.js）→ HTMLをブラウザに返す

jsへの記述

```javascript
// /topにリクエストが来たときにトップ画面を表示する
app.get('/top', () {
// トップ画面を表示する処理を記述
}
```
※URLに対応する処理を実行することをルーティングと言う

## reqとresについて
- ルーティングの処理ではreq(リクエスト)・res(レスポンス)の２つの引数を受け取る。
- reqとresにはリクエスト・レスポンスに関する情報が入っている。

jsへの記述

```javascript
// /topにリクエストが来たときにトップ画面を表示する
app.get('/top', ( req, res) => {
// トップ画面を表示する処理を記述
}
```

## EJSについて
- HTMLとjavaScriptのコード両方を記述できるNode.jsのパッケージ。

jsへの記述

```javascript
// /topにリクエストが来たときにトップ画面を表示する
app.get('/top', ( req, res) => {
// top.ejsを表示する
 res.render('top.ejs');
}
```

EJSをインストールする

```console
$npm install ejs
```

### EJSを使用した値の表示
- javaScriptのコードを記述するには<% %>または<%= %>で囲む。
 - <% %>の場合はブラウザに何も表示されないため、変数の定義に使用する。
 - <%= %>の場合はブラウザに表示される。変数の値を表示させたい時など。

- res.renderと書くことで指定したビューファイルをブラウザに表示できる
※見た目を作るファイルをビューファイルと呼ぶ

### EJSを使うメリット
- 繰り返し記述しているコードをスッキリ書くことができる
- forEachを利用するとスッキリ書くことができ、管理しやすくなる

EJSへの記述

```javascript
<% const items = [
   {id: 1, name: 'ねこ'},
   {id: 2, name: 'いぬ'},
   {id: 3, name: 'うさぎ'}
];%>

<% items.forEach((item) => {%>
   <li>
      <span class="id-column">
          <%=item.id %>
      </span>
      <span class="name-column">
          <%=item.name %>
      </span>
   </li>
<% }); %>
```

## CSSの適用方法
jsへの記述

```javascript
// cssフォルダ内のファイルを読み込む
app.use(express.static('css'));
```

EJSへの記述

```html
// 指定したcssファイルを読み込む
<link rel = "stylesheet" href ="css/style.css">
```
Nodejs Eslintの初期化設定で失敗した時の対応方法

# Nodejs Eslint 初期化設定で失敗した時の対応方法
**npm install eslint@^x.xx --save-dev** コマンドを実施したあと、eslintをインストールし、
初期化を実施しようと、**.\node_modules\.bin\eslint --init**コマンドを実施、
How would you like to configure ESLint? の質問に対して Answer questions about your styleを選択しEnterを押したところ、そこから何の進展もなかった時、その解決方法を共有します。

## 環境の整理
- 開発環境：Windows10 Home　64ビットオペレーティングシステム、x64ベースプロセッサ
- Node version: v12.xx.xx
- ESLint version: v4.19.1

## 現象
![not.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/ca3437cc-d99b-a69d-14b5-375e21df2adb.png)

## 解決方法
1. Nodejsの公式サイト（ https://nodejs.org/ja/ ）にアクセスし、node versionをダウンロード、アップデートする。
（　今回 Node version: v14.15.3　に更新　）

2. 問題なく、進んでいることを確認する。
![yes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/02dfd347-4b2e-7106-8142-49e83506e655.png)

OK
[ JavaScript入門 ] JavaScriptとECMAScriptの関係性について


#JavaScriptとECMAScript

Javascriptで開発していると、よく耳にするのが**ECMAScript**。　　
実際これってなんの？:upside_down:


##歴史
1990年代、**Netscape Navigator**というブラウザが存在。
そこに現れたライバル:spy_tone4:というのが**Internet Explore**というブラウザ。
　　
Internet Exploreはみなさんご存知の通り、Microsoft社が開発したブラウザ。
Windowsと一緒にInternet Exploreを配布することによってシェアを拡大していったよ:muscle:
　　
そこでNetscape Navigatorが考え出したのが、**JavaScript**
MicrosoftもJavaScriptを使いたい！！　けどライセンスの関係で使えない:cry:
そこでMicrosoftが作成したのが**JScript**  

この二つのプログラミング言語には互換性がない:frowning2:　　

そこで考え出されたのが**ECMAScript**:hugging:


##ECMAScriptとは　　
**JavaScriptのコアな部分を言語仕様として切り出したもの！**  

よってECMAScriptはJavaScriptのコアな部分の仕様ってことなのです:nerd:　　
これによって仕様が統一されて開発者の人がハッピーに:metal:　　
ただこれは**プログラミング言語の仕様なのでこの仕様をもって実装されたのがJavaScript**ということになる。　　

 [ECMAScriptの詳細はこちら](https://tc39.es/ecma262/)

##JavaScriptとは　　

JavaScriptの一部がECMAScriptということになるので　　
これ以外にも環境によって持っている機能が異なってくる:thinking:　　

| 環境    　　| 仕様             　　　　|    
|:-----------|-----------------------:|
| ブラウザ環境 | ECMAScript , Web APIs  |    
| Node.JS    | ECMAScript , Common.JS | 
  
**JavaScriptは実行する環境で使える機能が変わってくる:hugging:**

##まとめ　　

 `JavaScriptはECMAScriptの使用に基づいて実装されているプログラミング言語`
`JavaScriptは実行する環境で使える機能が変わってくる`
[Angular] 「基本的なAngularアプリをはじめる」をやってみる(1)

#「基本的なAngularアプリをはじめる」をやってみる(1)

[[Angular] 「基本的なAngularアプリをはじめる」をやってみる(準備)](https://qiita.com/IwashiMorino/items/3325a4a3f7fe6692c259 "[Angular] 「基本的なAngularアプリをはじめる」をやってみる(準備)")

昨日、上記の記事のようにチュートリアルのサンプルプロジェクトを生成しました。

サンプルプロジェクトを生成しますと、下図のように、
![015a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897250/fc4475d3-35bb-a997-b60b-cd7f8ca0cdb4.png)
product-listフォルダー、top-barフォルダーにそれぞれ css、html、ts、の3つにファイルができていることが分かります。

実行結果としてプレビュー画面には、下図のように表示されています。
![014a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897250/bb3f2736-ec77-eb55-5526-5b0f843ed757.png)

###ちょっとだけ、テストしてみる

今日は、ちょっとだけテストしてみます。

```typescript:product-list.component.ts
export class ProductListComponent {
  products = products;
  test_1 = '製品';
```
product-list.component.ts に test_1 = '製品'; を書き加えてみます。

```html:product-list.component.html
<h2>Products</h2>
<h2>{{ test_1 }}</h2>
```
product-list.component.html に \<h2>{{ test_1 }}\</h2> を書き加えます。

![016a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/897250/7ccdbe3d-6ff2-4a67-daca-a1ac1254b0e7.png)

はい。test_1 の内容が表示されました！

次の記事 ： [[Angular] 「基本的なAngularアプリをはじめる」をやってみる(2)](https://qiita.com/IwashiMorino/items/a11376f060639c3b4c74 "[Angular] 「基本的なAngularアプリをはじめる」をやってみる(2)")
Power BI Desktop で欠損がある時系列データの折れ線グラフを連続にする

## はじめに

Power BI Desktop で時系列データを折れ線グラフにした場合、データに欠損があると折れ線グラフも途切れます。
データが無かった場合、値を 0 として折れ線グラフを連続的に描画してみます。

つまり、こんなデータが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/767e5783-52ac-dbb6-cc9d-e2b625851b88.png)

こうなるのを
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/ec4b4e2e-78db-0f5e-6498-df2f5790005b.png)

こうしたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/18346424-a418-2be4-824d-b2fe387096fa.png)



## データの無い項目の表示

そもそも初期状態ではデータが無ければ表示されません。上記の例の場合、このように4月, 5月を除いたグラフが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/033fbee4-aada-f25a-fe70-b84074a7ff0e.png)

この場合、「視覚化」タブの「軸」から「データのない項目を表示する」をチェックする事で表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/564ab0fe-e86b-f145-f26c-134535ecdf0e.png)

ただし、値が null となるので、この場合数値の 0 に変換する必要があります。


## メジャーの追加

新しいメジャーを作成し、以下のように DAX を記述します。
既存のカラム「金額」を集計した結果に 0 を加算しています。ここは [こちらの記事](https://qiita.com/rintaromasuda/items/6a90c6c0da829dd59584) を参考にさせていただきました。

```
合計金額 = 
CALCULATE(
  SUM('Data'[金額])
) + 0
```

これにより、データが無い場合は 0 を値として持つようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/23962e98-38ef-a7af-1304-31ae4e3ccc75.png)

グラフも連続的になりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64309/f853cc45-1185-be1b-38b2-c1adef4ba617.png)


## おわりに

Power BI Desktop でデータの無い項目の値を 0 として折れ線グラフを連続的に描画しました。今回は参考記事そのままに「0 を加算する」やり方で簡単に実現できました。

Power BI は初めて使いましたが、DAX を使いこなす事が出来れば色々出来て面白そうですね。


## 参考

- [Power BIでテーブルをフィルタして値を計算するとき、"+ 0"を追加しておくと便利 - Qiita](https://qiita.com/rintaromasuda/items/6a90c6c0da829dd59584)
- [【PowerBI】存在しない欠損データにダミーデータを入れる - Qiita](https://qiita.com/ogaki_takahiro/items/80b3773464902a378086)
え、アイコンでまだFontAwesome使ってるの？？？

先に謝っておきます。いきなりタイトルから煽ってしまい申し訳ありません。

皆さん、Vue.jsでサイトを作る際にアイコンなどは何を使っていますか？

恐らくhtml,cssを学んで直後の人はFontAwesomeを使っているかと思います。

ただ、Vue.jsでFontAwesomeを使うのって結構面倒なんですよね。

FontAwesomeのパッケージをインストールしたり、一つ一つのアイコンをインポートしたり、その後に``<fa-icon>``なんて面倒以外の何物でもない。。。

今回は、そんな方に必見！！！

Vuetifyを使うことで、驚くほど簡単にアイコンを使う方法をご紹介します！

初心者の方だけでなく、中級者の方でFontAwesomeを使っている方にも見てもらいたい記事なので、ぜひ学習の参考にしてください！！（本当に簡単です）

それでは順を追って、一緒に説明を見ていきましょう！

#プラグインのインストール#

Vue.jsのプラグイン（Vuetify）をインストールします。

下記のコマンドを入力してください。

```
yarn add vuetify
```

<font color="red">※注意</font color>　``npm install vuetify``これだと一部機能が動作しな場合があるので、``yarn add``で実行してください。

#アイコンを決める#

次に、[https://iconify.design/](https://iconify.design/)にアクセスし、下にスクロールし``Material Design Icons``という項目をクリックしてください。

ここで、自分が使いたいアイコンのキーワードを入力します。（今回はemailを使います）

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/77a99251-271a-55af-2537-eaed697576a3.png)

すると、このような画面になると思います。ここから好きなアイコンをクリックします。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/de78ba71-e9c6-792c-b8ae-b9043393544b.png)

そして、すぐ下にこのようなことが書かれていると思います。この``mdi-~``を使って、アイコンを表示したいページに以下のように記述します。

```App.vue
<v-icon 
   style="color: #fff； margin-right: 10px;"
>
mdi-email-edit-outline
</v-icon>
メールアドレス変更
```

デフォルトではアイコンの色は黒なので今回は白色に設定します。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/9512e59f-3d7d-cc9e-ebf7-c3f25e5f4e86.png)

このようになるかと思います。

FontAwesomeを使うより断然楽だと思います。

フレームワークって機能が充実していて楽しい！！！

以上、「え、アイコンでまだFontAwesome使ってるの？？？」でした！

もう一度言います。タイトルで煽ってしまい申し訳ありませんでした。

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
Vue.js スコープ付きスロット

## はじめに
vueを学習していてスコープ付きスロットとはなんなのか？なぜこれが必要なのか？という疑問が解消したのでまとめます。スロットという概念を理解されている方を想定しています。

## スロット

まずはApp.vue（親）とMyBook.vue（子）を用意します。今回は子コンポーネントで定義しているデータ(Book,Userに関する情報)を親コンポーネントの方で利用してみたいと思います。

```vue:App.vue

<MyBook>
  <template v-slot:default>
    {{book.title}} ({{book.price}}円)<br>
    購入者:{{ user.name }}
  </template>
</MyBook>

```

```vue:MyBook.vue

<template>
  <div>
    <slot name='default'>{{book.title}} ({{book.publish}})</slot>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      book: {
        title: 'これからはじめるvue.js実践入門 ',
        price: 3000,
        publish: 'SBクリエイティブ'
      },
      user: {
        name: 'sin-sudo',
        age: 20,
        gender: 'male'
      }
    }
  }
}
</script>

```

このコードで期待するのはデフォルトで設定されている、本のタイトル:出版社名を親コンポーネントの方で本のタイトル:本の値段で置き換えるというものです。

![スクリーンショット 2021-01-04 19.15.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574301/f5830b20-2167-d88f-7b18-c0ea31149642.png)


画面的にはこのようになると思い通りに動作しているということになるのですが、今の状態でブラウザを確認してみると、

![スクリーンショット 2021-01-04 19.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574301/362e2bae-06a6-f44f-0ec7-e1096f274c54.png)

こんな感じのエラーがたくさん出て怒られてしまいますね。

これは親コンポーネントでのデータは親コンポーネントが、子コンポーネントのデータは子コンポーネントが管理するというvueの思想があるからなんですね。

親コンポーネントのテンプレートは親コンポーネントの管理下にあるので基本的に親から子のデータにアクセスすることはできません。ここで利用するのがスコープ付きスロットです。これを使うことで子コンポーネントのデータにアクセスすることができるようになります。

先ほどのファイルを以下のように編集します。

```vue:App.vue

<MyBook>
  <template v-slot:default='slotProp'>
    {{slotProp.book.title}} ({{slotProp.book.price}}円)<br>
    購入者:{{ slotProp.user.name}}
  </template>
</MyBook>

```

```vue:MyBook.vue

<template>
  <div>
    <slot name='default' v-bind:book = 'book' :user = 'user'>{{book.title}} ({{book.publish}})</slot>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      book: {
        title: 'これからはじめるvue.js実践入門',
        price: 3000,
        publish: 'SBクリエイティブ'
      },
      user: {
        name: 'sin-sudo',
        age: 20,
        gender: 'male'
      }
    }
  }
}
</script>

```

#### 今の編集で行ったこと

1. MyBook.vueでbookとuserに関してv-bindディレクティブで単方向のデータバインディングをした。
2. App.vueでv-slot:default='slotProp'として子コンポーネントからスロットプロパティを受け取れるようにした。
3. スロットプロパティからそれぞれの情報（book,user）を参照した。

#### スロットプロパティとは？

スロットプロパティとは何でしょうか？スロットプロパティはslot属性でバインドされているプロパティのことです。今回で言うとbook,userとなります。
親コンポーネントの方でslotProp(名前は任意)とすることで子コンポーネントからスロットプロパティをオブジェクト形式で受け取ることができます。

```
slotProp: {
  book: {
        title: 'これからはじめるvue.js実践入門',
        price: 3000,
        publish: 'SBクリエイティブ'
      },
      user: {
        name: 'sin-sudo',
        age: 20,
        gender: 'male'
      }
}
```

イメージこんな感じですかね。これで親コンポーネントの方で{{ slotProp.book.title }}などのようにしてアクセスすることができるようになります。

## 最後に

スコープ付きスロットの使い方についてまとめました。間違いあれば是非ご指摘お願いします。
manimの作法 その7

#概要

manimの作法、調べてみた。
ImageMobject、使ってみた。

#サンプルコード


```
from manimlib.imports import *
import numpy as np
from enum import Enum

class Color(Enum):
	WHITE = (255, 255, 255)
	YELLOW = (0, 255, 255)
	CYAN = (255, 255, 0)
	GREEN = (0, 255, 0)
	MAGENTA = (255, 0, 255)
	RED = (0, 0, 255)
	BLUE = (255, 0, 0)
	BLACK = (0, 0, 0)

class test(Scene):
	def construct(self):
		n = 256
		imageArray = np.uint8([[i * 256 / n for i in range(0, n)] for _ in range(0, n)])
		img0 = ImageMobject(imageArray)
		img0.set_height(7)
		img0.shift(2 * UP)
		img1 = ImageMobject(np.uint8([[0, 100, 30, 200], [255, 0, 5, 33]]))
		img1.set_height(7)
		img1.shift(2 * UP)
		width = 256
		height = 256
		color_img = np.zeros((height, width, 3), dtype = np.uint8)
		bar_width = 32
		i = 0
		for c in Color:
			color_img[0: height, i: i + bar_width] = c.value
			i += bar_width
		img2 = ImageMobject(color_img)
		img2.set_height(7)
		img2.shift(2 * UP)
		matrix = np.uint8([[0, 0, 200], [255, 0, 33]])
		img3 = ImageMobject(matrix)
		img3.scale(3)
		mat = np.uint8([[[0, 0, 0], [0, 0, 0], [0, 0, 200]], [[0, 0, 255], [0, 0, 0], [0, 0, 33]]])
		img4 = ImageMobject(mat)
		img4.scale(3)
		self.play(ShowCreation(img0))
		self.wait()
		self.play(ShowCreation(img1))
		self.wait()
		self.play(ShowCreation(img2))
		self.wait()
		self.play(ShowCreation(img3))
		self.wait()
		self.play(ShowCreation(img4))
		self.wait()





```

#生成した動画

https://www.youtube.com/watch?v=mDAbs6f-PGQ

以上。
git ローカル（自分のディレクトリー）にリポジトリ―を作る方法

# gitにリポジトリを作成する

> ##### 自分のディレクトリ―にリポジトリーを作成する方法

```
> git init 
```

すると自分のディレクトリーにリポジトリ―が作成されます。
Pardot Engagement Studio (Pardot Lightning アプリケーション) ⇒ Engagement Studio での時間と一時停止の操作

１．[待機最大時間] 設定の機能を説明する文を選んでください。
２．Engagement プログラムが一時停止されたときに、プロスペクトに期待される動作は何ですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/b4b04416-885e-023c-2c83-d2d0c2e48974.png)
中間テーブルに保存する時に、バリデーションエラーが発生した。

##中間テーブルにidsで配列の処理を行おうとしたらバリデーションエラーが出た
###userテーブル
| Column   | Type   | Options     |
| -------- | ------ | ----------- |
| name     | string | null: false |
| email    | string | null: false |
| password | string | null: false |

###roomテーブル
| Column | Type   | Options     |
| ------ | ------ | ----------- |
| name   | string | null: false |

###room_userテーブル
| Column | Type       | Options                        |
| ------ | ---------- | ------------------------------ |
| user   | references | null: false, foreign_key: true |
| room   | references | null: false, foreign_key: true |


```Ruby
# viewの記述
<select name="room[user_ids][]">
  <option value="">チャットするユーザーを選択してください</option>
  <% User.where.not(id: current_user.id).each do |user| %>
    <option value=<%=user.id%>><%= user.name %></option>
  <% end %>
</select>
<input name="room[user_ids][]" type="hidden" value=<%= current_user.id %>>
```
#
```Ruby
# controllerの記述

  def create
    @room = Room.new(room_params)
    if @room.save
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def room_params
    params.require(:room).permit(:name, user_ids: [])
  end
end
```
ここまでの記述に関しては、問題なく動作するので、変更することはなかった。

##急に中間テーブルにuser_id保存ができなくなった。
原因はわからないが、全く関係ない作業をしているときに急にバリデーションエラーが発生し、値が保存できなくなりRoomモデルも保存できなくなった。


##解決した方法

理由がわからないので、少し強引なやり方かもしれないが、解決する方法がこれしかなかったので、これでうまく動作してくれました

```Ruby
  has_many :room_users
  has_many :users, through: :room_users, validate: false
# validate: false　追記
```

バリデーションを行わない記述をすることで、中間テーブルに値を配列で渡し、うまく保存することができました。
get_the_terms()を使って、公開された記事が登録されているタームの一覧を取得する方法

#どうも7noteです。いろいろ調べて結局wordpressの関数では標準装備されてなかったので無理やり取得したった話。

登録されているタームの一覧や、記事が存在する（下書き・非公開を含む）タームだけを取得するのは`get_terms()`でできるが、
**`get_terms()`だと公開されている記事が登録されているタームだけ取得することができません**でした。

## 解決方法

```php
$posttype = 'ここにポストタイプ';    // 投稿タイプ
$taxonomy = 'ここにタクソノミー';    // タクソノミー

$posts = get_posts( array(
  'post_type' => $posttype,
  'taxonomy' => $taxonomy,
  'posts_per_page' => -1,        // 「-1」で全投稿取得
  'post_status' => 'publish',    // ←重要：公開記事のみ
));
foreach ( $posts as $post ){ 
  $pub_term = get_the_terms($post->ID,$taxonomy,);  /* 投稿IDをひとつずつチェック */
  foreach ( $pub_term as $key => $value ){          /* 取得したターム情報でループ */
    if($value->parent == "0"){                      /* 私は親タームのみを取得したかったので、ifをかましていますが必要なければとばしてください。 */
      $tarm_list[$value->slug] = $value->name;  /* 連想配列として、タームのスラッグとターム名を配列に格納 */
    }
  }
}

var_dump($tarm_list);
// （例）出力結果
// array(2) { ["blog"]=> string(9) "ブログ" ["news"]=> string(9) "お知らせ" }

// （使用例）
echo "<ul>";
foreach($tarm_list as $sluga => $namea){
	echo "<li>".$sluga."は".$namea."</li>";
}
echo "</ul>";
// （例）結果
/*
<ul>
  <li>blogはブログ</li>
  <li>newsはお知らせ</li>
</ul>
*/

```

**解説**

`get_terms()`では公開情報がとれないので、先に`get_posts()`を使って対象となる記事の一覧を取得します。
取得した記事の一覧から投稿IDをもってきて、**`get_the_terms()`を使って登録されているターム情報を取得します。**
ターム情報が取得できたら、そこから必要な情報（上の例ではslugとname）をひっぱってきて、連想配列に格納する。
（私は親タームのみ取得したかったため、if文を挟んでいます。）
あとは作成した連想配列を使って好きなように加工して吐き出すだけです。

連想配列で取得しているため、ダブりがあれば自動的に上書きされているので最終的にダブりがなくなりますが、
通常の配列などで取得する場合は`array_unique()`などで最後にダブりを削除する処理を追記してください。


#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
PyPIへの登録にユーザー名とパスワードを使うのはやめよう。APIトークンを使おう

# はじめに

[PyPI](https://pypi.org/) へパッケージを登録する記事を見ているとユーザー名とパスワードを渡す例が多く散見されました。

**それは古いやり方なのでやめてください。**

最近のPyPIはセキュリティにも力を入れており、APIトークンの仕組みを持っています。

[PyPI now supports uploading via API token](https://pyfound.blogspot.com/2019/07/pypi-now-supports-uploading-via-api.html)

一般に、この手のAPIの認証にはユーザー名/パスワードを使うよりAPIトークンを使う方がセキュアに運用できると言われています。

この記事ではPyPIへの登録時に、ユーザー名/パスワードではなくAPIトークンを使う方法を紹介します。

# PyPIでAPIトークンを作成する

はじめに、PyPIでAPIトークンを作成します。

1. PyPIにログインする
2. [Add API token](https://pypi.org/manage/account/token/) のページで `Token name` と `Scope` を埋めた後 `Add Token` ボタンを押下する
    * Token name: 好きな値を入れてください
    * Scope: すでにパッケージプロジェクトが登録済みの場合は `Project: <パッケージ名>` が選択できます。`Entire account (all projects)` という選択肢も表示されますがこれは全プロジェクトで有効なAPIトークンなのでセキュリティの観点からはおすすめしません
    ![スクリーンショット 2021-01-04 14.03.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82681/9734bc68-bf8e-a7c9-f553-b99f7a32ea10.png)
3. 結果生成された`pypi-` から始まる長い英数字列がAPIトークンとなります（ `pypi-` もAPIトークンの一部です）。これをメモ帳などにコピペしておいてください
    ![スクリーンショット 2021-01-04 14.02.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82681/b3434cc2-1662-e459-7084-85f81b1e04bb.png)

# PyPIにAPIトークンを使って登録する

つぎに、PyPIに、APIトークンを使ってパッケージを登録します。

PyPIへの登録サーバーは依然としてユーザー名/パスワード型のインターフェースしか用意されていませんが、登録サーバーは **ユーザー名欄に固定値 `__token__` を指定すると、パスワード欄の値をAPIトークンだと認識するようになります** 。

最近はPyPIへの登録には [twine](https://pypi.org/project/twine/)  そのものを使うよりも  [Poetry](https://github.com/python-poetry/poetry) や [Pyflow](https://github.com/David-OConnor/pyflow) といったパッケージマネージャーを使う方が主流です。
ここでは使ったことのあるPoetryとtwineのやり方を記載しますが、twineでもPoetryでもPyflowでもユーザー名に `__token__` を指定し、パスワードにAPIトークンを指定するのは変わりません。

CLI上でAPIトークンを指定する方法のみ紹介しています。
どちらの場合も設定ファイルに記載しておく方法は存在しますが、git等のファイル管理システムに管理下に（誤って）入ってしまいAPIトークンが外部に晒されてしまう可能性があるので紹介しません。
ファイル管理でやりたい場合は各自検索してみてください。

## PoetryでPyPIにAPIトークンを使って登録する

```bash
poetry publish --build -u "__token__" -p "＜APIトークン＞"
```

## TwineでPyPIにAPIトークンを使って登録する

```bash
twine upload -u "__token__" -p "＜APIトークン＞"
```

# おわりに

以上です。
CircleCIでssh秘密鍵を設定する方法

##記事の内容
CircleCIで自動デプロイを設定したい時のssh秘密鍵の登録の方法です。
初めて、CicleCIによる自動デプロイをする人は、参考になるかもしれません。
##前提
●Railsアプリ作成中
●CircleCIによる自動テストを導入済
●Capistranoを使ってAWSにデプロイ済

##ssh秘密鍵を登録する方法
CIrcleCIで、プロジェクトを選択後、"Project settings >> SSH KEYS >> Add SSH key" を選択すると、Host NameとPrivate Keyを記入するように求められます。
ここで、Host Nameは、ドメインか、IPを設定します。
Private Keyは、 ローカル環境から、EC2にログインする際に使用する秘密鍵の中身を記述します。
まず、秘密鍵が作られているか確認します。秘密鍵を~/.sshに格納している場合は、

```
[~]% cd ~/.ssh
[.ssh]% ls
known_hosts	〇〇〇〇.pem
```

上記のように、鍵の名前が表示されます。
ここで、私はPrivate Keyに、〇〇〇〇.pemと打ちましたが、うまくいきません。それは、単に秘密鍵の名前だからです。
そこで、以下のコマンドを打つと、秘密鍵の中身が表示しました。※ 中身は、適当です。

```
[.ssh] % cat 〇〇〇〇.pem
-----BEGIN RSA PRIVATE KEY-----
abjapojbnaopherj4123np9wg8uangq43bano3
bnaojegopajger234-gqonjgqpenogqoo51qu8

...bawneopgaoeuaopvewajbojewobnaoebja2
-----END RSA PRIVATE KEY-----%  
```

ここで表示された内容を
'-----BEGIN RSA PRIVATE KEY-----'から、'-----END RSA PRIVATE KEY-----%  'までコピーして、Private Keyにペーストすれば、秘密鍵を設定することができます。


以上になります。sshしたいサーバーの秘密鍵を設定に役立つと嬉しいです。
[Rails エラー] unexpected tIDENTIFIER

# はじめに

よく出るエラーです。

いちおメモします　:snowman2:


# 問題

Rspecのテストを書いているときにエラーが起きてしまいました。

```ruby

SyntaxError:
  /Users/namae/projects/picapp/spec/models/user_spec.rb:8: syntax error, unexpected tIDENTIFIER, expecting end
  ...'ユーザー新規登録'　do
  ...                          ^~~~~
  /Users/namae/projects/picapp/spec/models/user_spec.rb:20: syntax error, unexpected end, expecting end-of-input
    end
    ^~~
```

# 調べた結果

「SyntaxError」とはじめにあるように構文のエラーです。
カンマが抜けていたり空白が足りなかったり全角スペースがあったり・・
　　　　　　　　　　　　　　　　　　　　　　　　　するとエラーが発生します。

# まとめ

よくあってはいけないのですが・・気をつけなくてはいけないですね。
Volley に headers を付加する（Kotlin）

Kotolin で Volley を使っていて、API アクセスの際に headers に認証情報を付加したかったので、やり方メモ



```kotlin
val queue = Volley.newRequestQueue(this)
val url = "アクセス先 URL"

val stringRequest = object: StringRequest(Request.Method.GET, url,
	Response.Listener{ response ->
		val toastText = response.toString()
		Toast.makeText(this, toastText, Toast.LENGTH_LONG).show()
	},
	Response.ErrorListener{
		// Error 処理
	})
{
	override fun getHeaders(): MutableMap<String, String> {
		val headers = HashMap<String, String>()
		headers["Authorization"] = "必要なアクセスキー情報"
		return headers
	}
}

queue.add(stringRequest)
```
【AWS】CodeComｍitとは？Githubとの違いとメリットについて。

個人用メモです。

##CodeCommit(コードコミット)の役割
AWS上のソースコードやファイルの管理システム。役割はgithubと同じ。

**コードのアップロード、履歴の確認、プルリクエストなど**ができる。

<br>
**■メニュー一覧**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/dd715140-5436-f6b8-43d5-f6b7a25ced4d.png)|
|:--|

<br>
##Githubとの違い
Githubとの違いは、**CodeCommitの方がセキュリティが高い**こと。

Githubの場合、Privateにしているプロジェクトでも外部の開発関係者と丸ごと共有する場合がある。

このとき、AWSなどのサーバーのアカウント情報やPWなど共有してはいけないコードがGithubにあれば、それらも共有されてしまうため、セキュリティ観点でNG。


<br>
##CodeCommitの用途
上述のとおり、**AWSのアカウント情報などプロジェクトの管理者のみが所持しておくべき情報を保存**しておく。

CodeCommitにアクセスする際にAWSのユーザーIDとPWが求められるため、それらを知っている人しかアクセスできず、セキュリティが高い。


<br>
##使い方

###レポジトリの作成
Github同様にレポジトリを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/bb7f5eb6-7d07-0d43-326b-60fb2e814526.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/dba514b3-8fad-a8d1-4571-4697a4a4e411.png)
(説明はなくてもいい)



<br>
###ファイルの追加
ファイルの追加方法は３種類

1. AWS上で作成する
2. ファイルを選択してアップロードする
3. レポジトリのURLにプッシュする

初回はファイルをアップロードが基本的な使い方かな。

その後はローカルにこのレポジトリをクローンしてリモートレポジトリとして登録する。

CodeCommitのレポジトリと接続するためには**IAMユーザーにCodeCommitへのアクセス権限を付与**する必要がある。

<br>
**▼クローン手順例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/8ab96996-158d-4b51-65b3-06ba32e52af9.png)

```:cloneの手順例
#clone
git clone https://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo my-demo-repo

#レポジトリを登録
git remote add [レポジトリ名] https://git-codecommit.us-east-2.amazonaws.com/v1/repos/MyDemoRepo

#レポジトリ登録状況の確認
git remote -v
```


<br>
>
・[IAMユーザーにCodeCommit権限を付与する方法](https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html#managed-policies)
・[CodeCommitレポジトリへのHTTPSでの接続手順](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-connect.html)


<br>
##コミット履歴の確認
左カラムのコミットから各コミットの詳細や履歴を確認することができる。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/7d0f4f5e-925c-0a39-e564-69fc8c4fcc65.png)|
|:--|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d4421a4b-cd74-54c3-4ad3-8a200b429a41.png)


- コミット：各コミットIDを選択するとコミットの差分が確認できる。
- コミットビジュアライザー：グラフ形式で履歴が確認できる。
- コミットの比較：　ブランチどうしで差分の比較ができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/4171dd25-532c-08e6-be86-23f157d3feb8.png)


<br>
**▼コミットビジュアライザーの例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/1383777e-f7be-33f4-02ad-21f9bf2e317b.png)


<br>
##通知設定
コミットやプルリクがあった場合に通知するよう設定することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/17a0328f-aa90-bb14-2b2a-5e5bbcbda9df.png)


トリガーは自由に設定可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/e7b99d89-2aa8-ca9b-06ba-a79fda361ce6.png)



<br>
##レポジトリの削除
削除も簡単にできる。
指定のテキストを打ち込む仕様はGithubと同じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/56816a9a-73f3-84b2-0cdb-95e241f66af8.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/eab27915-c825-d6b5-4a1a-55155dc18fe1.png)
ホントに身につく本の読み方

社会人二年目の商品開発部門で働くエンジニアです．
博士号を取得したものの，専門とは大きく異なるソフトエンジニアに近い職種のため
プライベートの時間も技術書などを読みながら何とか食いつないでいます．
上流工程・要求仕様の検討も多いため最近はビジネス書籍もよく目を通します．
本が累積してくると，
・並行して読み進めるので中途半端な進捗の本が複数発生する
・結局読みきらない本が増える
**ただ本を読んだ気になっていることってありませんか？**
私はよくあります（した）．

一般的な読書法を大別すると
・速読
・深読
ちゃんと理解しようと思うと速読は向いてないし，深読するにはインプットすべき本が多すぎる（インプットできる時間も限られている）．

そこで私が提案したいのは**"整読"**です．
これから紹介する内容は至って当たり前の内容ですが，自分はこれを始めてから本の定着度が格段に改善しました．

##整読について
**[方法]**
・読んだ本のポイントを箇条書きレベルで纏める．これだけ！(情報を整理して読む=整読．以降このノートを整読ノートと呼びます．)
・作成した整読ノートを１ヶ月後に読み返す．
**[ポイント]**
・ボリュームは後で読み返したときに，本のポイントを10分で説明できる程度に（決して全ての内容を記述しない）．
・前半を注力するビジネス書であれば，全ページ数の前から25%程度に筆者が本当に伝えたいことが書かれているケースが多いです．
・自分が理解できる形で良い（人に見せるつもりでまとめなくても良い．）ただし，あとから読み返したときに思い出せるレベルに記述する．
**[メリット]**
・整理する過程で自分なりにポイントを抽出するので，”本当に大事な要素”が明確になりやすい．つまり話の幹を残して，枝をカットできる．（この作業が深読よりも早く，速読よりも深く理解できることが整読の肝．正直本の記述内容全てを覚えるのはナンセンスで，その本のエッセンスを体に身につけることができればオールOKとする）

##整読ノートの例
![Screen Shot 2021-01-04 at 12.53.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934349/5415fdd2-63ef-1228-223e-926613982989.png)

##詳細
#####ノート
メモ帳でも，紙のノートでもなんでも良いです．が，私はiOSのNotesをオススメします．メリットとしては
・iphoneでも気軽に纏められること．icloudで共有されるのでMac,iPadからもアクセス可能
・本の画像などを挿入すると，上記の例のように一覧化した時にサムネイルとして表示されるのでわかりやすい（なんかやってる感もある）
・写真挿入が用意（iphoneからのスキャン機能がデフォルトで存在）

####記述タイミング
大体，一章を読んだら記述してます．背景から記述し始めるとまだ，全容や掴みどころもわからない．２章とかまで進んでしまうと，ポイントが纏めにくくなる．


##最後に
たぶん多くの人が自分なりの本の読み方を実践しつつ，自己研鑽に励まれていると思います．
ここでは自分なりの方法を超簡単に纏めました．
ご意見，よりよい方法あればアドバイスほしいです．