OmniAICreator/Qiita-1.07M huggingface dataset:
【WordPress】検索

# カスタム投稿タイプの件数指定

__概要__

カスタム投稿タイプの件数指定

__施策__

```php
/*--------------------------------------------------------
// カスタム投稿タイプの件数指定
--------------------------------------------------------*/
function links_display_articles( $wp_query ) {
	if (!is_admin()):
		if ( $wp_query->is_main_query() && $wp_query->is_post_type_archive( 'news' ) ) {
			$wp_query->set( 'posts_per_page', 20 ); // 1ページ当たり件数
		}
	endif;
}
add_action( 'pre_get_posts', 'links_display_articles' );
```

----

# 検索結果にカスタム投稿タイプも含める

__概要__

検索結果にカスタム投稿タイプも含める

__施策__


```php
/*--------------------------------------------------------
検索結果にカスタム投稿タイプも含める
--------------------------------------------------------*/
function filter_search($query) {
	if ( is_search() && !is_admin()):
		if ($query->is_search) {
			$query->set('post_type', array('post', 'page', 'news'));
		};
	endif;
	return $query;
};
add_filter('pre_get_posts', 'filter_search');
```

---

# 特定の記事を検索結果から除外する

__概要__

特定の記事を検索結果から除外する

__施策__


```php
/*--------------------------------------------------------
特定の記事を検索結果から除外する
--------------------------------------------------------*/
function fb_search_filter($query){
	if ( is_search() && !is_admin()):
		if ( !$query->is_admin && $query->is_search) {
			$query->set('post__not_in', array(1328,1330,1375,1377) ); // 記事ID配列
		}
	endif;
    return $query;
}
add_filter('pre_get_posts', 'fb_search_filter');
```

---


# 検索結果からショートコードを削除

__概要__

検索結果からショートコードを削除

__施策__


```php
/*--------------------------------------------------------
// 検索結果からショートコードを削除
--------------------------------------------------------*/
function remove_shortcode_from_index( $content ) {
	if ( is_search() && !is_admin()):
		$content = preg_replace('/\[[^\]]+?\]/', '', $content, -1);
	endif;
	return $content;
}

add_filter('the_title', 'remove_shortcode_from_index');
add_filter('the_excerpt', 'remove_shortcode_from_index' );
```

---

# カスタムクエリー

__概要__

カスタムクエリー

__施策__


```php
/*--------------------------------------------------------
// カスタムクエリ一
--------------------------------------------------------*/
//追加したいカスタムクエリ一覧
function query_list(){
	$arr = array(
		'shop'
	);
	return $arr;
}

//クエリとして動作するようにする
function add_meta_query_vars( $public_query_vars ) {
	foreach(query_list() as $val){
		$public_query_vars[] = $val;
	}
	return $public_query_vars;
}
add_filter( 'query_vars', 'add_meta_query_vars' );

//上記追加したクエリが存在した時の記事抽出
function meta_search_query($query) {
	if ( is_admin() || ! $query->is_main_query() ){
		return;
	}

	foreach(query_list() as $val){
		$query_val = $query->get($val);
		if($query_val){

			$query->set('meta_query',
				array(
					array(
						'key' => $val,
						'value' => $query_val
					)
				)
			);
		}
	}
}
add_action( 'pre_get_posts', 'meta_search_query');

//カスタムクエリの有無で読み込まれるテンプレートを変更する
function custom_template($template){
	global $wp_query;

	foreach(query_list() as $val){
		if($wp_query->get($val)){
			$template = dirname( __FILE__ ) . '/archive-news.php';
		}
	}
	return $template;
}
add_filter( 'home_template', 'custom_template' );
```
HTTPを理解する⑦ HTTPSの仕組み

webサイトを利用する際、クレジットカードの番号や個人情報などが悪意あるなりすましサイトによって盗まれる危険性があります。こういった脅威から重要な情報を守ってくれる仕組みとしてHTTPSがあります。

## HTTPS
HTTPSとはSSLやTLSを利用することでHTTP通信の安全性を高めるための仕組みです。実際はSSL/TSLプロトコルが作り出す安全な接続を使って、その上でHTTPを使用します。
以下の三つの仕組みでwebサイトの安全性を確保しています。
### 暗号化通信による盗難防止
webサイトを閲覧する時の通信は複数のサーバーを行き来します。そのため通信内容を第三者が覗くことは不可能ではありません。そこで覗き見られてもいいようにデータを暗号化して防ぎます。

### 改ざん防止
データの送受信時にハッシュ値を比較して改ざんを検知できる。

### webサイトの運用元の確認によるなりすまし防止
webサーバーにSSLサーバー証明書を置いておきます。接続時に証明書を確認することで接続先が本当に自分が行きたかったところか確認することができる。
PHPのCI用にDockerfile作成した

## 前置き

PHPのバージョン管理はできないので（ご存知の方がいれば教えてください）、CIのための環境をDocker作りました。
また、PHPのCIを回すために色々インストールが必要だったりと、手順が多くなりやすいです。

DockerでPHPもPHPUnitもphpcsも用意すれば、Dockerを実行できる環境だけ用意すれば良くなるので、作りました。

## 使い方

GithubからDockerfileをコピーしてくるか、DockerhubのImage(sunouchi/php_ci)を指定して、
`docker run`してください。

## Github

Dockerfileだけ置いてます。改造したい場合、phpのバージョンを変更したい場合はGithubから取得してください。
https://github.com/Sunochi/Dockerfile/blob/master/php_ci/Dockerfile

## Dockerhub

まだlatestのみです。
諸々の説明はいつか書きます。
https://cloud.docker.com/repository/docker/sunouchi/php_ci

## 参考

[DockerImageをDockerHubに登録の仕方](https://qiita.com/kon_yu/items/7c40f4dfbd1cce006ce7)
Node Slack SDKを使用してNode.jsからSlackAPIを叩く

# はじめに
Node.jsからslack apiを使用するには[Node Slack SDK](https://slack.dev/node-slack-sdk/)が便利です。
本記事は`@slack/web-api`のサンプルコードとなります。

## install
```
npm install @slack/web-api
```

## 実装例

```javascript:slack.js

require('dotenv').config()
const { WebClient } = require('@slack/web-api');
const token = process.env.SLACK_TOKEN;
const web = new WebClient(token);

exports.postMessage = async () => {
  // Post a message to the channel, and await the result.
  // Find more arguments and details of the response: https://api.slack.com/methods/chat.postMessage
  const result = await web.chat.postMessage({
    text: 'Hello world!',
    channel: '#test',
  });

  // The result contains an identifier for the message, `ts`.
  console.log(`Successfully send message ${result.ts}`);
}

exports.fileUpload = async () => {
  // Just use the `file` argument as the documentation suggests
  // See: https://api.slack.com/methods/files.upload
  const result = await web.files.upload({
    filename: 'test.txt',
    channels: '#test',
    content: 'aaaa',
    initial_comment: 'best',
  })

  // `res` contains information about the uploaded file
  console.log('File uploaded: ', result.file.id);
}
```

## 動作確認
```bash

$ node
> const slack = require('./slack.js');
> slack.postMessage();
> slack.fileUpload();
```

## 実行結果
<img width="761" alt="スクリーンショット 2019-05-30 23.59.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226008/edd401a8-a989-df2b-386b-f99ffd8d688b.png">
HTML4日目

少しずつ理解してきた。。。超初心者レベルだけど、少しずつ知識を増やせて行けて、楽しい。

##フォームバリデーション
- バリデーション: 入力された内容が要件を満たしているか、妥当性を確認すること（？）
ちょっと何言ってるかわかんないっすね（富沢風）
<br>↓<br>
入力しないままサブミットすると「入力してください」的な。

```
		<form action="#" method="post">
			<label for="username">名前を入力してください</label>
			<input id="username" name="username" required>
			<input type="submit" value="送信">
		</form>
```

- label: フォームの項目名を表示
labelのfor=inputのid →　ラベルをクリックして、フォームを選択できるようにする。
Docker + rails + Webpacker で buildしたときに　COPY のstepでエラーが出る

Dockerを使ってRails＋Webpackerで環境構築しようと思ったら以下のようなエラーに遭遇した。

```
ERROR: Service 'webpacker' failed to build: COPY failed: stat /var/lib/docker/overlay2/7a5a91db824e62b94de842827e48bdea3dc9c4d2d36c17134fcf61c8bf8dfdc9/merged/opt/yarn-v1.13.0: no such file or directory
```

### Dockerfile
```
FROM node:10 as node
FROM ruby:2.6.2

ENV LANG C.UTF-8
ENV YARN_VERSION 1.13.0

RUN apt-get update -qq && apt-get install -y build-essential graphviz libpq-dev

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
    apt-get install nodejs

COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/

RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

RUN gem install bundler

CMD ["/bin/sh", "-c", "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"]

```

全く同じ構成でも動く人と動かない人（自分）が存在して解決に時間がかかった。


### 原因
自分がDockerでの環境構築を始めたのが**遅かった**から。
もう少し具体的に言うと、Dockerを使い始めたのが遅かった為、指定したversionのyarnをコンテナ内にCopyできず、冒頭にあるようなエラーが発生していた。
`ENV YARN_VERSION 1.13.0`という指定を、 `COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn` でしており、今回でいうと　`FROM node:10 as node` でpullしてきたベースのイメージから、yarnの1.13.0をコピーさせる命令を出しているが、そのVersionのyarnを扱ったnodeは自分のimageにはなく、pullしてきたnodeの中にもない（同じ構成で構築できた人は以前使ったyarn1.13.0が自分のimagesに存在しており、Dockerの仕組み上ローカルにベースイメージがあればそれを使い、もしなければDockerHubからpullする為、ローカルのimageを使って結果buildできた）為、そんなファイルやディレクトリはないと怒られていた。

### 解決策
copy時のVersion指定をワイルドカード（あるいは最新版などの指定nodeに存在するVersionを選ぶ。）

```
FROM node:10 as node
FROM ruby:2.6.2

ENV LANG C.UTF-8
＃＃Yarnのバージョン指定は不要

RUN apt-get update -qq && apt-get install -y build-essential graphviz libpq-dev

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
    apt-get install nodejs

COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn  <== ここの[v$YARN_VERSION]　で環境変数指定でCopyしようとしていた部分を[*]ワイルドカードにする。
COPY --from=node /usr/local/bin/node /usr/local/bin/

RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

RUN gem install bundler

CMD ["/bin/sh", "-c", "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"]

```
これで、指定nodeの中から、使えるversionのyarnをCOPYしてbuildする事ができるようになる。


実際の業務などでは、そもそもDockerを使う理由としてLocalでの開発環境から開放されたいのに、Docker内のモジュールのバージョンが各自違うというのはアレなのでbuildしたものを全員で共有して開発するというやり方がよい。
【画像生成】Encoder-LatentSpace-Decoderで分類に基づいたカテゴリ毎画像生成♬

やりたいことは、カテゴリ毎に画像生成すればさらに詳細化した画像生成や段階的な分類が可能になるだろうということである。
今回は、詳細化された画像生成をやってみた。
イメージは以下のとおり、入力画像をカテゴライズ、その結果に基づいてカテゴリーごとに学習済みの専用のEncoder－Decoderを使って画像生成する。
![eld.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/bda4e1df-cb28-e9ac-4e16-df06927e86e7.jpeg)
以下はCifar10のグレー画像化して、彩色した例（カテゴライズもグレー画像で実施）
![autodetect_cifar20_test_rand_s10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/14ca23fb-6fbf-be5d-4fe9-b83de34cbb4a.jpeg)
※上からグレー画像、次が０－９の専用Encoder-Decoderで生成、三段目が１０個を一つのEncoder-Decoderで学習したもので生成、最後の段が元のカラー画像
###やったこと
・MNISTについてカテゴリー毎Encoder-Decoderで画像生成
・Cifar10についてカテゴリー毎Encoder-Decoderで画像生成
###・MNISTについてカテゴリー毎Encoder-Decoderで画像生成
コードは以下のコードで学習します。
・[VAE/keras_category.py](https://github.com/MuAuan/VAE/blob/master/keras_category.py)
そして、上記の話は学習済のモデルを利用して以下のコードで実施します。
・[VAE/keras_category_intelligence.py](https://github.com/MuAuan/VAE/blob/master/keras_category_intelligence.py)
その結果以下の画像が得られました
![autodetect_mnist.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/f2d8566e-e98a-b4d9-7750-81d5d8b21158.jpeg)
十分な精度で得られました。
###・Cifar10についてカテゴリー毎Encoder-Decoderで画像生成
Cifar10に同様なことを実施しました。
通常の画像生成はMNISTと同様にかなりの精度で画像生成できたので、ここでは、特に彩色について説明します。
コードは以下のコードで学習します。
・[VAE/keras_category_cifar10_color.py](https://github.com/MuAuan/VAE/blob/master/keras_category_cifar10_color.py)
そして、上記の話は学習済のモデルを利用して以下のコードで実施します。
・[VAE/keras_category_intelligence_cifar10_color.py](https://github.com/MuAuan/VAE/blob/master/keras_category_intelligence_cifar10_color.py)
結果は上に示したとおりとなりました。
ところが、同じように０だけ学習したEncoder-Decoderで画像生成したものが以下のとおりになりました。
![autodetect_cifar20_test_rand_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/afdf35b4-71d0-aa7f-f5b1-3d66d05bf629.jpeg)
並びは上記の場合と同じですが、カテゴリは全て０となっています。もちろん、カテゴライズは正しくカテゴライズしていますが、生成のEncoder-Decoderは０のAirplaneのみを学習したものです。
それでも、比較するとわかりますが、第二段目と三段目を比較すると、ほとんど同じような画像を生成しており、ほぼ着色できているのが分かります。

これは以前[DLの記憶で見た現象](https://qiita.com/MuAuan/items/2a51771b7943c5887ab7)と同じような現象だろうと思います。
あの現象はLatentSpaceの次元が大きくなると学習していないカテゴリも生成できるようになりました。
これ以上の内容は今回は不明なのでさらに追及していきたいと思います。
###まとめ
・分類に基づいてカテゴリ毎学習済のEncoder-Decoderで画像生成をやってみた
・カラー化も実施できた
・０のみの学習済Encoder-Decoderで、０－９のすべてを学習したEncoder-Decoderと同じ彩色結果となった

・Encoder-DecoderのLatentSpaceの役割をさらに追及しようと思う
・もう少し複座なものでDLの記憶やロジックを含むニューロを考えてみよう
【Ansible】Windowsドメインアカウントで接続する

# はじめに
WindowsのActive Directoryは、ユーザ認証にKerberos認証を採用しています。
そのため、AnsibleのWinRM接続でWindowsドメインアカウントを使用する際は、Kerberos認証を利用します。
AnsibleでKerberos認証を利用するにはpython kerberosモジュールが必要です。

また、Ansibleで利用するWindowsドメインアカウントは、ターゲットマシンの管理者権限が必須です。

本記事は、オフライン環境で行った手順をまとめています。

##Ansible側の環境
+ OS：CentOS7.6
+ Ansible：Ansible2.7
+ pywinrmインストール済み

##Windows側の環境
本記事では、例として以下の値を利用します。

+ ドメイン：example.com
+ Active Directory：windows001
+ Windowsドメインアカウント：admin
+ ターゲットマシン：windows002 , windows003

#1. python kerberosモジュールをインストールする
まずはKerberosのクライアントパッケージをインストールします。

```bash
$ yum -y install krb5-devel krb5-libs krb5-workstation
```

以下のパッケージを任意の作業フォルダにコピーします。

+ kerberos-1.3.0.tar.gz
+ requests-kerberos-0.12.0.tar.gz
+ pykerberos-1.2.1.tar.gz

作業フォルダに移動し、python kerberosモジュールをインストールします。

```bash
$ pip install -f ./ --no-index kerberos-1.3.0.tar.gz
$ pip install -f ./ --no-index requests-kerberos-0.12.0.tar.gz
```

#2. Kerberosのクライアント設定をする（大文字・小文字に注意）

```/etc/krb5.conf
# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/

[libdefaults]
 default_realm = EXAMPLE.COM

[realms]
 EXAMPLE.COM = {
  kdc = windows001.example.com
  admin_server = windows001.example.com
  default_domain = example.com
 }

[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
```

#3. Windowsドメインアカウント名でトークンの問い合わせを行う

```bash
$ kinit admin
```

パスワードの入力を求められるので、パスワードを入力します。

以下のコマンドでトークンチケットが取得できていることを確認します。

```bash
$ klist
```

#4. hostsファイルを編集する

```text:/etc/ansible/hosts
[windows]
windows002
windows003

[windows:vars]
ansible_user=admin@EXAMPLE.COM
ansible_password=<パスワード>
ansible_port=5986
ansible_connection=winrm
ansible_winrm_transport=kerberos
ansible_winrm_server_cert_validation=ignore
```

これでwindows002 , windows003に対してPlaybookが実行できるようになります！
CentOS7.6にPHP7.3をyumでインストールする

今回はPHP7.3をインストールしてみる:baby_tone2:

#CentOS7.6にPHP7.3をyumでインストールする

まずは、おまじない。

```console
$ sudo yum install epel-release
$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

必要最小限でインストール。

```console
$ sudo yum install --enablerepo=remi-php73 php
```

バージョンを確認する

```console
$ php -v
PHP 7.3.6 (cli) (built: May 28 2019 09:32:59) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.6, Copyright (c) 1998-2018 Zend Technologies
```
よしゃ:ok_hand_tone2:
php7.1の時とほぼ一緒ですた :stuck_out_tongue_winking_eye:
【入門】SourcetreeとGitHubの連携の手順

# はじめに

これまで、職場でのバージョン管理はSubversion、自宅でのバージョン管理は適当...でしたが、先日に縁があってSourcetreeを使ったGitHubの利用方法を教わることができました。
そこで、まずはSourcetreeとGitHubを連携させて、自宅でGitHubを使える環境をセットアップしてみました。

この記事は、そのセットアップ作業の備忘録ですが、初心者・入門者の方に何らかの形でお役に立てれば幸いです。

# 事前準備

1. GitHubのアカウントを作成します。
 * GitHubのアカウントを先に作っておくと、後の流れがスムーズになります。 
 * 2019年現在だと、[こちらの記事](https://qiita.com/okumurakengo/items/848f7177765cf25fcde0)が参考になるかもしれません。

# Sourcetreeのインストール（for Windows）

## ダウンロード

* [Sourcetreeのサイト](https://www.sourcetreeapp.com/)から、Windows版をダウンロードします。
* [Download for Windows]をクリックした後、ソフトウェアライセンスとプライバシーポリシーに同意すればダウンロードが開始されます。

## Install

* インストーラを起動して、最初の画面でBitbucketのアカウントと紐づけます。

![Sourcetree_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/5b109ee3-235b-0793-7fc6-210e38b95264.png)

* Bitbucketのアカウントが無い場合は、前の画面で［Create one for free.］をクリックして、Atlassianのアカウントを作ります。
 * アカウントを新規作成する場合は、インストーラの画面からブラウザに遷移します。
 * この時、Googleアカウントなどを使ってAtlassianのアカウントを作ることができます。

![Sourcetree_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/045e1245-b724-cbd1-892d-2410636dfa94.png)

* 最後に一意なユーザー名を設定します。
 * 単純な名前だと既に登録されている可能性が高いので、ユーザー名はちょっと工夫する必要があるかもしれません。

![Sourcetree_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/3f8a0903-a20b-29e8-3268-6e099dc360a9.png)

* Bitbucektとの紐づけが完了すると、再びインストーラの画面に戻って、Atlassianのアカウント（※墨塗り部分）が表示されます。
  
![Sourcetree_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/038d10db-44c4-da4d-2897-11c0ee5b417a.png)

## Registration

* 次の画面でインストールするツールを選びますが、今回はGitしか使わないため、Mercurialのチェックを外して［次へ］をクリックします。

![Sourcetree_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/87e151d1-260f-f6c6-728b-7552114c8ae4.png)

## ツールをインストール

* 「ツールのインストールが完了しました。」のメッセージが出て、インストール作業が終わりかと思いますが、［次へ］を押してさらに進みます。

![Sourcetree_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/28cac71b-cac5-a25e-1585-cca347590c18.png)

## Preference

* "Preference"の画面は、先程に紐づけたAtlassianのアカウントおよびBitbucketの一意なユーザー名がデフォルトで表示されているため、そのまま何も変更せずに［次へ］をクリックします。

![Sourcetree_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/24dafde8-9396-c1f4-7c2d-13c9ad52aad9.png)

# GitHubとの紐づけ

* Sourcetreeを開き、［Remote］画面に入った後、［＋アカウントを追加］をクリックします。

![Sourcetree_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/ce464706-f35a-e085-e3ce-fa6ad6b35b59.png)

* ［ホスティングアカウントを設定］画面で、ホスティングサービスをGitHubに設定します。
* 続けて、［OAuthトークンを再読み込み］をクリックします。

![Sourcetree_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/b029ce6b-ab8e-072a-871c-b1e4cc5d22c4.png)

* ［OAuthトークンを再読み込み］をクリックすると、SourcetreeからGitHubへのアクセスを許可する画面が表示されるので、［Authorize atlassian］を押して承認します。
 * ここまでの作業で、SourcetreeからGitHubを使うための準備は完了となります。

![Sourcetree_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/33824e69-abf2-1476-f1e1-380fa08d561e.png)
[GraphQL][AWS AppSync] 概念をざっくり解説 (1)



以下の記事でGraphQLの勉強記事を書いて、それからだいぶ時間が経ってしまいました。AppSyncのチュートリアルなどを通してなんとなく雰囲気がわかってきたので概要を掴むための記事を書いてみます。
https://qiita.com/hassaku_63/items/d12d36d17cce536ade66 

詳細な解説は[Qiita - GraphQLって何？](https://qiita.com/syu_chan_1005/items/3350f1d12c17a77e98c7)が詳しいのでそちらに譲ります。

# 参考

- [GraphQL - Introduction](https://graphql.org/learn/)
- [How to GraphQL](https://www.howtographql.com/)
- [AWS Documents - チュートリアル AWS AppSync](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/tutorials.html)
- [AWS Amplify - Get Started](https://aws-amplify.github.io/docs/js/start)

# GraphQLとは

ランタイムとインタフェース、文脈によって意味するところは違うようですがこのいずれかを示します。

大事なことは**「データストアの実装方法詳細には関知しない」**ということです。あくまでも「GraphQLという方言によってデータのやり取りのインタフェースを取り決めできる」と言っているに過ぎない。

AWS AppSyncはGraphQLのマネージドサービスであると謳っていますが、これはデータストアの実装がいい感じに他のAWSサービスにラップされて提供される、という意味でありGraphQLという言葉そのものが意味する定義よりもAppSyncは広い概念だと言えます。

GraphQL的にはインタフェースが先にあって、裏のデータストアのことはインフラ組む人がよしなにしてね、と。

必然的に、インタフェースと実装（データストア層）を結びつけるマッピングのための何かが必要になります。このマッピングを定義する要素を、AppSyncでは（その役割の通り）リゾルバと呼んでいます。

AppSyncではDynamoDBを使うのが一般的だと思われますが、Lambda functionを使うことも可能です。

# GraphQLで定義するもの

インタフェースとして、以下のような要素を備えています。

- データ形式の定義
- CRUDを担う「操作」の定義

どちらも、プログラミング言語で言うところのクラス・構造体・インタフェースに近い何かだと思っておけば良いと思います。いずれも宣言的なフォーマットで記述します。この定義に従ってデータを取り扱います。

# GraphQLランタイムと実装を結びつけるもの

先ほども記述したように、リゾルバを使って定義します。
AppSyncとDynamoDBの例でいくと、例えばこういう感じ

```
GraphQL 「新しいUser型のデータを追加するためのCreateUserという操作を宣言する」
リゾルバ「CreateUserが呼ばれたら、DynamoDBのPutItemオペレーションに変換するための変換ルールを宣言する」
```

リゾルバはデータストアの実装にも関わってくるので、こちらはGraphQLというよりAppSyncの仕様です。

ユーザーがリゾルバに関して行う必要があるのは「マッピングテンプレート」の定義です。[Apache Velocity Template Language (VTL)](http://velocity.apache.org/engine/1.7/user-guide.html)というテンプレート言語を使って記述します。実際のデータストアへの操作を実行する機能はAWSが裏でよしなにするので、ユーザーはその変換ルールをテンプレートでもって宣言してあげます。

詳細はこちら [AWS - リゾルバーのマッピングテンプレートの概要](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/resolver-mapping-template-reference-overview.html)
# つづく

ここからはスキーマを使って実際の定義を見ていくわけですが、このへんの構文とその意味付けがいまひとつ理解できてないのでまた次回にしようと思います。

サーバーサイド側のルールである「スキーマ」と実際のリクエストの形式が似ているので、その区別を整理していくともうちょい理解が捗りそうな気がしてます。

以上。
DNN_前編

##Day 1

####要点
https://qiita.com/taktakeuchi/items/8fb8b4ac7a7e6f4ff86a

####確認テストの考察
https://qiita.com/taktakeuchi/items/923c7e9c166490ecd5ed

####Jupyter演習
https://qiita.com/taktakeuchi/items/d6a47428002c258cf390

####修了課題
https://qiita.com/taktakeuchi/items/420c5b11f3e3a80445ab


##Day 2

####要点
https://qiita.com/taktakeuchi/items/5863aa38e030e92b2dba

####確認テストの考察
https://qiita.com/taktakeuchi/items/09e0938f2d04487ddd3a

####Jupyter演習
https://qiita.com/taktakeuchi/items/edfdb1d8481004041f87
Ruby on Rails [学習記録-第11章-]

#n+1問題
* モデルを利用してデータベースの情報にアクセスする際にはSQLが発行されます。SQLが発行されるたびにデータベースに対して通信が走るので、SQLが大量に発行されれば処理が重くなります。n+1問題とは、データを呼び出す際に大量のSQLが発行されてしまう問題のことです。
* 今回の場合、indexアクションで全ツイートを取得する1回に加えて、アソシエーションを利用してツイートの数だけユーザー情報を呼び出しています。つまり、現在の状態だとapp数＋1回SQLが発行されています。この状態のことをn+1問題と言います。

#includesメソッド
* includesメソッドはn+1問題を解消することができる。
* 指定された関連モデルをまとめて取得することで、SQLの発行回数を減らすことができる。
* 書き方は、`includes(:モデル名)`
* appsテーブルのレコードは必ず1つのusersテーブルのレコードに属しているので、includesメソッドを利用することでappsテーブルのレコードを取得する段階で関連するusersテーブルのレコードも一度に取得することができる。

```rb:apps_controller.rb
class TweetsController < ApplicationController

  def index
    @tweets = Tweet.includes(:user).page(params[:page]).per(5).order("created_at DESC")
  end

  #以下省略

end
```
DockerでWordPress環境構築の際にハマったこと

#はじめに
WordPress開発環境の構築をする際に、以前はVagrant+VirtualBoxを利用していましたが、最近GCPにDockerコンテナのデプロイをしてみようと思うようになりました。
その過程で、ハマったことを覚え書きしておきます。

#環境構築
サーバー環境の準備からbedrockのインストールまで、[こちら](https://qiita.com/kyasu1/items/5c9aeda8f8aea5e2fe5d)を参考にさせていただきました。

#WordPressの日本語化
ハマった訳ではないけど、覚え書き程度に書いておきます。
composer.jsonを編集することで、日本語化も出来ます。

```composer.json
"repositories":[
 {
  "type": "composer",
  "url": "https://wpackagist.org"
 },
 {
  "type": "composer",
  "url": "https://wp-languages.github.io"
 }
],
"extra": {
 "installer-paths": {
  "public/wp-content/plugins/{$name}/": ["type:wordpress-plugin"]
 },
 "dropin-paths": {
  "public/app/languages/": ["vendor:koodimonni-language"],
  "public/app/languages/plugins/": ["vendor:koodimonni-plugin-language"],
  "public/app/languages/themes/": ["vendor:koodimonni-theme-language"]
 },
 "wordpress-install-dir": "public"
}
```

最後に、

```
$ composer require koodimonni-language/ja:*
```

を実行したら日本語化完了です。


#ハマったこと
##その①　413 「Request Entity Too Large」
bedrockのインストールまで終わりテーマのアップロードをしようとすると、「413 Request Entity Too Large」の表示。
調べていると、デフォルトのnginx設定だと、最大アップロードが1MBになっているようで、これを変更しないといけないようです。合わせてPHP側でもアップロードの最大容量が設定されているので、そっちも設定しておかなくてはいけないようです。
する事は、

* client_max_body_sizeの変更
* post_max_sizeの変更
* upload_max_filesizeの変更

client_max_body_sizeは/etc/nginx/nginx.conf中にあります。
post_max_size、upload_max_filesizeは/etc/php.iniの中にあります。今回は、upload_max_filesizeが小さかったようです。

##その②
その①が解決し、再度テーマのアップロードを試みると、今度は「ディレクトリwp-content/uploads/を作成できませんでした。
この親ディレクトリのアクセス権はサーバーによる書き込みを許可していますか？」のような表示。どうもFTP接続が必要なのだそうです。これを回避する方法は、wp-configに

```wp-config
define('FS_METHOD', 'direct');
```

と追記します。さらに、upgrade、themes、plugins、languagesのディレクトリ権限を変ます。

```
$chmod 0707 app/****
```

##その③
WordPressをインストールして使っていると、パーマリンク設定を変更後、「404」が表示されるようになりました。.htaccessが無かったので作成してみましたが、変わリませんでした。そもそも、nginxで.htaccessは不要だったようで。nginx.confを変更しないといけないようでした。

```etc/nginx/default.template.conf
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name ${NGINX_HOST};

    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html;

    location / {
        try_files $uri $uri/ @wordpress;
    }

    location ~ \.php$ {
        # try_files $uri =404;
        try_files $uri @wordpress;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location @wordpress {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/wp/index.php;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```
無事、パーマリンク設定を変更できるようになりました。
Threat Modeling: ソフトウェアの脅威を洗い出す手法

Threat Modeling の概要と STRIDE を使った脅威探しの方法を紹介する。

## Threat Modeling 概要

Threat Modeling とはリスクマネジメントの一種であり、ソフトウェアに存在する潜在的な脅威を洗い出すプロセスのことを言う。

ソフトウェア開発における Threat Modeling の目的は、セキュリティの問題を早期に発見することによって、修正によるコスト発生を抑えつつ、安全なプロダクトをデリバリーすることにある。

なお、脅威によるリスクを評価し低減することも含めて Threat Modeling ということもあるが、この記事では脅威を洗い出すことに焦点を当てる。


## Threat Modeling の例

Threat Modeling がどんなものかをざっくり把握してもらうために、スマホゲームを例に説明する。

ここではスマホゲームの脅威を「健全なゲーム運営を阻害するもの」として、具体的にどんなものがあるんだろう？をひたすら探す。これが Threat Modeling.

下記は筆者が一人ブレーンストーミングで思いついた脅威の例。みんなも考えてみよう。

1. 「キャラクターのパラメータを不正に書き換え」られてゲームバランスを破壊される
2. 「データベースに侵入」されてプレイヤーの個人情報を奪われる
3. 「DoS攻撃」でゲームサービスを妨害される
4. 「大量のプレイヤーが同時にログイン」してゲームの応答が遅くなる
5. 「ディスク障害」でデータが消失する
6. 「オペミス」でメンテナンス時間が延長する

※「」内が脅威にあたる。脅威は"悪意のある攻撃"とは限らないことに注意

このように、ブレーンストーミングによる Threat Modeling は手っ取り早く始められる。そして、開発チームにセキュリティの専門家がいればそれなりにうまくいく可能性が高い。

ただしブレーンストーミングには次のような課題がある。

- より多くの脅威を見つけ出すには下記が必要
  - プロダクトへの深い理解
  - セキュリティ関連のスキルセット（攻撃手法、防御手法、一般的な脅威、など）
- 網羅性がわからない（十分に脅威を洗い出せたか？）
- レビューが難しい

なのでもうちょっと体系的なアプローチが欲しくなる。次にその一つである STRIDE を導入する。

## STRIDE

STRIDE とは、下記の表のとおり、代表的な6つの脅威の頭文字をとった略語。ちなみに STRIDE は情報システムが持つべき特性の逆転になっている。

|-|脅威|侵害されるシステムの特性|
|:--:|:--|:--|
|S|Spoofing<br>なりすまし|Authentication / Authenticity<br>認証 / 真正性|
|T|Tampering<br>改ざん|Integrity<br>完全性|
|R|Repudiation<br>否認|Non-repudiability / Accountability<br>否認防止 / 責任追跡性|
|I|Information Disclosure<br>情報開示|Confidentiality<br>機密性|
|D|Denial of Service<br>サービス妨害|Availability<br>可用性|
|E|Elevation of Privilege<br>権限昇格|Authorization<br>認可|

各脅威毎に検討する内容の例を上げる。

- Spoofing(なりすまし)
  - 他の人になりすます
  - 他の端末になりすます
  - 他のプロセスになりすます
- Tampering(改ざん)
  - ファイルを改ざんする
  - メモリを改ざんする
  - ネットワーク経路を改ざんする
- Repudiation(否認)
  - 「やってないよ」と言い張る
  - ログ（記録）がない
- Information Disclosure(情報開示)
  - プロセスから漏洩
  - データストアから漏洩
  - ネットワークから漏洩
- Denial of Service(サービス妨害)
  - プロセスへのDoS
  - データストアへのDoS
  - ネットワークへのDoS
  - 人へのDoS
- Elevation of Privilege(権限昇格)
  - プロセスの権限を奪う
  - 認可ロジックのバグ
  - ACLの設定ミス

## STRIDE を使った Threat Modeling の例

先ほどのスマホゲームの脅威探しに STRIDE を導入してみよう。6つの観点ベースで脅威を列挙できるので、いきなり始めるよりも整理しやすく、網羅性も可視化しやすくなる。

下記は筆者が STRIDE 観点でブレーンストーミングした例。みんなもやってみよう。

- Spoofing(なりすまし)
  - 他のプレイヤーになりすましてログインされる
  - 不正なプログラムから（ゲームクライアントになりすまされて）リクエストを投げつけられる
  - プレイヤーが偽のゲームサーバに接続させられてIDパスワードを盗まれる
- Tampering(改ざん)
  - キャラクターのパラメータを不正に書き換えて強化される
  - ゲームクライアントのコードを書き換えられて色々される
- Repudiation(否認)
  - 有料アイテムを購入してないのに課金されたというクレーム
  - 不正行為でバンしたユーザから異議申し立てされるとか？
- Information Disclosure(情報開示)
  - アプリをリバースエンジニアリングされてゲームの隠しデータを見られる
  - データベースに侵入されてプレイヤーの個人情報を奪われる
- Denial of Service(サービス妨害)
  - DoS攻撃でゲーム運営を妨害される
  - 大量に新規登録されてリソースが浪費される
  - 大量のプレイヤーが同時にログインしてゲームの応答が遅くなる
  - ディスク障害でデータが消失する
  - オペミスでメンテナンス時間が延長する
- Elevation of Privilege(権限昇格)
  - ゲームにログインしなくてもプレイできたりしない？
  - プレイヤーがバグを突いてGM権限でなんか実行できたりしない？

STRIDE を取り入れたことで列挙できた脅威の数が増加し、網羅性もそれっぽく見えるようになった。(前のブレーンストーミングでは Spoofing と Repudiation と Elevation of Privilege が漏れていた)

とはいえブレーンストーミングという手法をとっている以上、依然として属人化や網羅性の課題は残る。

## Next

次回は、よりシステマティックに脅威を列挙できるアプローチとして STRIDE-per-element と STRIDE-per-interaction を紹介する。
Vuex クラシックモードからの卒業 

Nuxt + TypeScriptでvuex書いてたら、ブラウザのコンソールにwarningが。

> Classic mode for store/ is deprecated and will be removed in Nuxt 3

Nuxtがv3になったらクラシックモードは廃止されちゃうそうな。
なので`このクラシックモードからの卒業`をすることに。

ただ、**actions, getters, mutations, state**を別ファイルでかつ、**nuxt-prpoerty-decorator(
vuex-class)**の実装例があまりなかったので残しとくことにした。

## ディレクトリ構成
nuxtのstore配下のディレクトリ
`modules`いらなかったかなとか思いつつ。ディレクトリの分け方は要検討。

```
store
├── index.ts
└── modules
    └── user
        ├── actions.ts
        ├── getters.ts
        ├── mutations.ts
        └── state.ts
```

## storeの実装
名前とかは適当なので寛大な心でみてください

indexいらないような気もした。

```typescript:index.ts
// stateのinterface呼んでる
import { RootState } from '@/model/rootstate'

export const state = (): RootState => ({
  version: '0.1.0'
})
```

公式のドキュメントにて
> オプションでモジュールファイルを state.js、actions.js、 mutations.js、getters.js といった別々のファイルに分離することができます。

って書かれてるので、ファイル名にactionsとか指定するだけでよしなにやってくれるんだろなと理解。
だいぶスッキリかけるんでないと感動。

```typescript:modules/user/actions.ts
import { User } from '@/model/user'

export default {
  // 本来はapiとやりとりするとこだけども簡略化
  setUserData({ commit }, user: User): void {
    commit('setUserData', user)
  }
}
```

```typescript:modules/user/getters.ts
import { UserState } from '@/model/user'

export default {
  // HACK: nullかどうかの分岐もっとかっちょよく
  getName(state: UserState): string | null {
    if (state.user) {
      return state.user.name
    }
    return null
  },
}
```

```typescript:modules/user/mutations.ts
import { User, UserState } from '@/model/user'

export default {
  setUserData(state: UserState, user: User): void {
    state.user = user
  },
  deleteUser(state: UserState): void {
    state.user = null
  }
}
```

```typescript:modules/user/state.ts
import { UserState } from '@/model/user'

export default function(): UserState {
  return { user: null }
}
```

## コンポーネントでstore呼びだしてみる
```vue
<script lang="ts">
import { Component, Vue, namespace } from 'nuxt-property-decorator'
const userModule = namespace('modules/user')

@Component
export default class VuetifyExample extends Vue {
  @userModule.Action('setUserData') setUserData
  // GetterやMutationも同じように書ける

  submit(userData: User | null): void {
    if (userData) {
      this.setUserData(userData)
    }
  }
}
</script>
```
decoratorがめちゃくちゃ優秀。出木杉くん。

`@userModule.Action`モジュールごとの呼び出しもスマート。感動。
技術志向エンジニアとサービス志向エンジニアについて思うこと

## 技術志向エンジニアとサービス志向エンジニアについて思うこと
技術志向エンジニアとサービス志向エンジニアという言葉があります。

サービスそのものよりも技術を重視するのが技術志向エンジニアで、技術よりサービスを重視するのがサービス志向エンジニアです。

なかなか的を射た分類と思われます。

ここで気をつけていただきたいのは、「自分はどっちなんだ...?」と悩む必要はないということです。
技術志向エンジニアといえどサービスのことを考えることもありますし、サービス志向エンジニアも技術のことを考える必要はあります。

技術対サービスの割合が0:10や10:0である必要がありません。
どちらにも興味があるのなら素晴らしいことです。「技術志向エンジニア兼サービス志向エンジニア」として前向きに頑張りましょう。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
DNN_前編 1 (演習結果と考察)

#深層学習1-6 Jupyter演習　（Section1：入力層～中間層）
#####【演習実施結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/85d6a9b2-9180-8e44-9ed4-013f8ccc2356.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/5483fab9-e31f-46b7-331e-393611ae9e48.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/174f8358-930c-cf6c-0a59-badf3185e860.png)

#####【考察】
内積を取る時は、入力の列の数と、重みの行の数を一致させる必要がある。一致していないとｴﾗｰになる。
numpyを使うと、パラメータの入力は、直接値を打ち込む以外に、0や1、また乱数を自動生成するようなメソッドが使える。


#深層学習1-8 Jupyter演習　（Section2：活性化関数）
#####【演習実施結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/1020256b-9388-9b82-9065-fa12f6a7d29e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/73e78b8b-bdc0-dcd4-3723-81684e7ea30c.png)


#####【考察】
処理自体は、単ノードの場合と同じ。
単ノードの時と異なり、今回は中間層のノード数が3なので、出力値も3つある。
数が多くなってくると、具体的な数値を冗長的に記述するよりも、np.random.rand()などを使用して、書けばソースコードは1行で済んで見やすくなる。



#深層学習1-15 Jupyter演習2
#####【演習実施結果】
1_3_stochastic_gradient_decent.ipynb
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/0ac59922-b348-49a0-d6d2-6c7fbaa368cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/f9f28585-1b2a-e13a-f992-49f74cda5f9d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/5f5c1d11-7284-c24e-242b-9bb491a2020e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/efa2dfe0-8f15-a4bc-bb96-217cce13a890.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/2b9ed5a7-0842-9185-a66a-b9efd30f162a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/9eaffbf8-eaa8-a9f8-9525-6a15b522700b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/b1ee9eba-e4d6-dfa3-2e7f-984611f592d5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/77eb3790-9f3a-9543-894d-138a90f45608.png)
順伝播でシグモイド関数を使った方が、学習にばらつきが出て来るのが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/bcaa0621-e522-ce69-b3f0-72c4e2c15e07.png)
全く収束していないのが分かる。


#####【考察】
同じネットワークモデルでも、使う活性化関数によって、結果が変わってくる。
またモデルだけではなく、与えるデータによっても、結果が変わる事が分かった。
windowsにunityを入れてみた

#追記
インストールするUntiyのバージョンについて、末尾にa,bとつくものはベータ版でありバグがあるので避けたほうがよいと教えていただきました。現在は2019.1.7f1が最新のリリース版だが、まだ情報が少ないのでその一つ前の~~2018系~~2018.4系をインストールするのがよいとのこと。
#はじめに
unityを初めてPCにダウンロード＆インストールしたので手順をメモ。
#環境
Windows10
#手順
1.unityの[公式サイト](https://store.unity.com/ja)にアクセスし、プランを選ぶ。今回はお試しなので左側にあるPersonalプランを選択した。Personalプランの欄の無料ダウンロードをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/bc7e1d69-38ec-b0ff-6020-2cc60f2b7b11.png)

2.クリックするとこのような画面が出てくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/d3e402bd-e7a5-0c78-a44f-557bcf7067f8.png)
利用規約をチェックするところがあるので利用規約を理解してからチェックをつける。チェックをつけるとUntiy Hubをダウンロードというボタンが青くなるのでクリック。

3.ダウンロードが始まる。
インストーラがダウンロードされる。ファイル名はUnityHubSetup.exe。このファイルを開きセットアップする。unity hubがインストールされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/daed811b-6233-0813-075d-c3cbc0170ef5.png)
こちらのソフトを開く。

4.untiy本体をインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/ecdf652a-f435-2d3c-83ac-f8ade1ffacd2.png)
(この画像ではすでにインストールされている）
右上のインストールという青いボタンを押しunityのバージョンとモジュールを選ぶ。今回は最新版を入れ、モジュールはDocumentationをいれた。（モジュールは後から追加することが可能みたい。。。試してないけど）

5.ライセンスを取得する。
この状態でプロジェクトを作成しようとしてもライセンスがありませんと怒られるので注意。
右上の歯車マークをクリックすると、左側にライセンス管理という項目があるのでクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/583b906f-8360-8b1d-42cc-02cf24e8c1cc.png)

ライセンスを管理するためにはunityのアカウントが必要なので右上のひとの形をしたアイコンをクリックし、ログインする。unityIDをもっていないときは作成しログインする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/358f481f-22bc-0dc5-567a-8783cd2db66e.png)
(画像ではライセンスが取得されている状態）
ログインしたら新規ライセンスの認証をクリック。Personalを選択し、自分のunityを使用する条件にチェックを入る。

これでライセンスが取得できた。

6.プロジェクトを作成する。
最初の画面に戻り。右横にあるプロジェクトの項目をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356269/5d820724-7afd-e758-4e07-52777a07fddf.png)
(この画像ではすでにプロジェクトが作成してある状態)
プロジェクトの新規作成をクリックして2D,3Dなどを選ぶ。これでunityでアプリケーション開発ができるようになる。

#まとめ
unityのサイトは日々刻々と変化する。
Ruby on Rails [学習記録-第10章-]

#アソシエーション
* アソシエーションとはモデル間の関連付けを管理する機能のことで、定義しておくことでモデルをまたいだデータの呼び出しをより簡単に行うことができる。
* 今回の場合、UserモデルとAppモデルをアソシエーションで関連付けする。
* アソシエーションを利用するには以下の2つの条件を満たす必要がある。
  * モデルクラスにhas_manyやbelongs_toなどの定義がされている。
  * 所属する側のテーブルに所属するクラス名_idというカラムがある。
* Userモデルの視点で考えると、あるuserの作成したappが複数個ある状態と言えます。この状態のことをhas manyの関係といい、今回の場合には「User has many Apps」の状態であると言えます。
* Userモデルのモデルファイルにhas_many :tweetsと追記する。

```rb:user.rb
  class User < ApplicationRecord
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :validatable
    has_many :apps
  end
```

* Appモデルの視点で考えると、全てのappはいずれかのuserに属している状態と言えます。
* この状態のことをbelongs toの関係といい、今回の場合は「App belongs to User」の状態であると言えます。

```rb:app.rb
class App < ApplicationRecord
  belongs_to :user
end
```
* 以上の作業でアソシエーションが定義できた。
* さきほど編集を行ったusers_controller.rbのshowアクション部分でのデータの呼び出しにアソシエーションを使用して記述を適用する。

```rb:users_controller.rb
class UsersController < ApplicationController

  def show
    @nickname = current_user.nickname
    @apps = current_user.apps.page(params[:page]).per(5).order("created_at DESC")
   #before: @apps = App.where(user_id: current_user.id).page(params[:page]).per(5).order('created_at desc')
  end
  end

end
```
用語

CDNとは、コンテンツデリバリネットワーク（Content Delivery Network）の略で、世界中に張り巡らされたCDN専用の配信ネットワーク（CDNプラットフォーム）を利用して、Webサイトにアクセスしようとするエンドユーザに最も近いPoP（配信拠点）から効率的かつ高速にWebを配信する仕組みです。
【Zabbix】jstatでjavaヒープ領域（heap memory）を監視することになった

◆やったこと
・監視対象サーバにて、jstatを用いてgcログを元に、Old領域の使用率を出力するスクリプトを作成
・スクリプトをcron設定で１分間隔で起動させる
・Old領域の使用率が９0％を超えると、Zabbixのログ監視で検知する

◆条件
・監視対象サーバで下記が使えること
　・Zabbix Agent
　　※監視対象サーバと監視サーバ間でZabbix Agentの通信が使えること
　・jstatコマンド
　・bcコマンド

◆環境
・OSはCentOS7、JavaはOpenJDK8(1.8)、監視サーバはZabbix3.0を利用。

◆作業
[監視対象サーバ]
必要なパッケージをインストールする。bcパッケージはヒープ領域の閾値計算にスクリプト内で利用。

```bash:

# yum install bc
# yum install java-1.8.0-openjdk-devel
```
gcログのモニター用スクリプトを設置。

```bash:gc_monitor.sh
#!/bin/sh
##

############################################
# 変数
############################################
PID=`/bin/jps |grep Bootstrap |awk '{print $1}'`
#GCログ出力先
LOGFILE=/var/log/tool/jstat_gcutil.log
#Zabbix監視用のログ出力先
CHECK_LOGFILE=/var/log/tool/jstat_check.log
OUR=`tail -1 ${LOGFILE}|awk '{print $5}'`
TV_1=80 #NOTICEレベルの閾値（％）
TV_2=90 #WARNINGレベルの閾値（％）

############################################
# 処理
############################################

##調査用ログ出力
echo -e "`date` ¥¥n `jstat -gcutil -t ${PID}`" >> ${LOGFILE}

##Old領域使用率チェック
OU_CHECK=$?

        if [[ ${OU_CHECK} = 0 ]] && [[ "$(echo "${OUR}< ${TV_1}" |/bin/bc )" -eq 1 ]] ;then

                  echo "`date +%Y%m%d_%H:%M:%S` Java HeapMemory(Old Area) Check OK" >> ${CHECK_LOGFILE}

        elif [[ ${OU_CHECK} = 0 ]] && [[ "$(echo "${OUR}> ${TV_1}" |/bin/bc )" -eq 1 ]] && [[ "$(echo "${OUR}< ${TV_2}" |/bin/bc )" -eq 1 ]] ;then

                  echo "`date +%Y%m%d_%H:%M:%S` Java HeapMemory(Old Area) over ${TV_1}% NOTICE" >> ${CHECK_LOGFILE}

        elif [[ ${OU_CHECK} = 0 ]] &&  [[ "$(echo "${OUR}> ${TV_2}" |/bin/bc )" -eq 1 ]] ;then

                  echo "`date +%Y%m%d_%H:%M:%S` Java HeapMemory(Old Area) over ${TV_2}% WARNING" >> ${CHECK_LOGFILE}

        else
                  echo "`date +%Y%m%d_%H:%M:%S` Java HeapMemory(Old Area) Check Failed" >> ${CHECK_LOGFILE}

         fi
exit
```

[監視サーバ]
Zabbix3.0にアイテム設定とトリガー設定を入れる。

アイテム設定
<img width="800" alt="zabbix-1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207381/35c2b12e-5d65-5d60-6fcd-8e8678d8853d.png">

トリガー設定　※条件式の抜粋
下記の通り、正規表現で"WARNING"の文言があるとステータス＝１となる。
あとは、アラート通知設定を入れればメールなどで通知可能。アラート通知設定は割愛。

```bash:トリガー設定
{ホスト名:log[/var/log/tools/jstat_check.log,,,,skip,].regexp(WARNING)}=1
```

以上となります。
ホスティングサービスとは

ホスティングサービスとはサーバの利用者自身でサーバの運営・管理をしなくてもいいように、有料または無料でサーバ機のHDDの記憶スペースや情報処理機能などを利用させるサービスを言う。 サーバホスティング、または「レンタルサーバ」、「共用サーバ」とも呼ばれる。
Leetcode #412: Fizz Buzz

```swift
func fizzBuzz(_ n: Int) -> [String] {
    var answer = [String]()
    for i in stride(from: 1, through: n, by: 1) {
        if i % 15 == 0 {
            answer.append("FizzBuzz")
        } else if i % 3 == 0 {
            answer.append("Fizz")
        } else if i % 5 == 0 {
            answer.append("Buzz")
        } else {
            answer.append(String(i))
        }
    }
    return answer
}
```
Ruby on Rails [学習記録-第7章-]

#ログイン機能の実装

##devise
* deviseは、ログイン機能を簡単に作成することができるGem。
* deviseを使用するためには、Gemのインストールに加えてdevise専用のコマンドを利用して設定ファイルを作成する必要がある。

```bash:
$ rails g devise:install
```

* deviseを利用する際にはアカウントを作成するためのUserモデルを新しく作成する。

##rails g devise コマンド
* deviseでログイン機能をつける概念のモデルを作成する際に利用するコマンド。モデルに加えて、ログイン機能のために必要なカラムが追加されるマイグレーションファイルなどが生成される。

```bash:
$ rails g devise user
# deviseコマンドでモデルを作成
```
* config/routes.rbに以下の様な記述が自動的に追記される。

```rb:routes.rb
Rails.application.routes.draw do
  devise_for :users
#以下略
```

* devise_forはログインまわりに必要なルーティングを一気に生成してくれるdeviseのヘルパーメソッド。
* 後ほど登場するcurrent_userやuser_signed_in?などのヘルパーメソッドも利用できるようになる。

#link_toメソッド
* このメソッドは引数を指定することで様々なリンクを生成できる。
* 通常HTMLコード内でリンクを生成する際にはaタグを使用する。link_toメソッドを使って記述を行うと、HTMLコードが読み込まれる際にaタグに変換されるので、サイトを表示した際にはaタグと同様に、リンクとして表示される。

```html:sample.html.erb
  <%= link_to 'ツイート一覧へ', '/tweets', class: 'sample' %>
  # 作成したaタグに`class="sample"`属性を付与
```

#user_signed_in?
* deviseでログイン機能を実装すると、user_signed_in?というメソッドを使用することができる。
* ユーザーがサインインしているかどうか検証するメソッド。
* サインインしている場合にはtrueを返し、サインインしていない場合にはfalseを返す。

```heml:sample.html.erb
<% if user_signed_in? %>
  # ユーザーがサインインしている場合に実行する処理
<% end %>
```

##Prefix
* Prefix(プレフィックス)とは、ルーティングのパスが入る変数のこと。コントローラやビューなどで呼び出すことで、prefixに入っているパスやURL情報を取得できるようになる。
* deviseを導入した場合、ユーザーの新規登録やログインに関するprefixは予め決まっており、以下のようになる。

| リクエスト | prefix | パス |
|:--------|:-------:|:--------:|
| devise/sessions#new　　　| new_user_session | /users/sign_in |
| devise/sessions#create 　| user_session | /users/sign_in |
| devise/sessions#destroy | destroy_user_session | /users/sign_out |

#redirect_toメソッド
* Railsでは通常、アクション内の処理が終了すると自動的にアクション名と同名のビューが表示される。
* ただしredirect_toメソッドをアクション内で利用すると、そこからさらに別のアクションを実行したり、ビューに遷移させたりできる。
* 引数にはaction: :indexという形で、キーがaction:バリューが:indexであるハッシュを指定する。

```rb:apps_controller.rb
class AppsController < ApplicationController

  def index
    @apps = App.page(params[:page]).per(5).order("created_at DESC")
  end

  private
  def move_to_index
    redirect_to action: :index
    # indexアクションを強制的に実行する
  end
end
```

#before_action
* Railsではコントローラでbefore_action :メソッド名と記述することで、コントローラのアクションが実行される前にそのメソッドを実行することができる。
* また、オプションonlyやexceptを使うことにより、before_actionを実行することをアクションごとに制限をかけることができる。

```rb:apps_controller.rb
class AppsController < ApplicationController

  before_action :hoge, except: :index
  # indexアクション以外が実行される前にhogeが実行される。

  def index
    @apps = App.page(params[:page]).per(5).order("created_at DESC")
  end

  private
  def hoge
  end
end
```
【ALE】eslint_dを使ってESLintの実行を高速化する

## やりたいこと

[eslint_d](https://github.com/mantoni/eslint_d.js/)を使用して、[ale](https://github.com/w0rp/ale)でのESLintの実行を高速化したい。

eslint_dを実行すると、バックグラウンドでサーバプロセスとして常駐し、ESLint実行時のオーバーヘッドを軽減してくれます。

## 導入

まず、eslint_dをインストールします。

```sh
$ npm install eslint_d -g
```

次にaleをインストールします。
以下はdein.vimを使用した際の設定例です。
`on_cmd`オプションを使って、指定されたコマンドが実行されるまでaleの読み込みを遅延しています。

```ini:dein.toml
[[plugins]]
repo = 'w0rp/ale'
on_cmd = ['ALELint', 'ALEToggle', 'ALEEnable', 'ALEToggleBuffer', 'ALEEnableBuffer']
```

vimrcにaleからeslint_dを使用するための設定を記述します。

```vim:設定例
" eslint_dを利用するための設定
if executable('eslint_d')
  let g:ale_javascript_eslint_use_global = 1
  let g:ale_javascript_eslint_executable = 'eslint_d'
endif

let g:ale_linters_explicit = 1
let g:ale_linters = {
  \   'javascript': ['eslint'],
  \   'typescript': ['tsserver', 'eslint'],
  \   'vue': ['eslint']
  \ }
```

## 確認

VimでJavaScriptファイルを開いて、`:ALELint`コマンドを実行します。

次にターミナルを開いて、以下のコマンドを実行します。

```sh
$ eslint_d status
```

うまく連携ができていれば、`Running. One instance cached.`のような内容が表示され、aleからeslint_dが実行されていることを確認できます。

## eslint_dを停止させる

eslint_dはバックグラウンドで常駐します。
停止させたいときは以下のコマンドを実行します。

```sh
$ eslint_d stop
```

## 参考

* [ale](https://github.com/w0rp/ale)
* [eslint_d](https://github.com/mantoni/eslint_d.js/)
QEMU による Ubuntu 16.04 x86_64ホストPC上への Ubuntu 16.04 aarch64(arm64) / coretex-A53 仮想環境の構築


# １．Introduction
Ubuntu 16.04 x86_64のホストPC上に Ubuntu 16.04 arm64(aarch64) の仮想環境を構築します。 64bit ARM用 のプログラムのビルド環境を構築するために手順を記録するものです。 ちなみに、私の目的とするビルド対象は、 Bazel と Tensorflow です。 この環境でビルドしたバイナリを RaspberryPi3 (aarch64) へ展開して使用することを想定しています。 

# ２．Environment
- Ubuntu 16.04 x86_64

# ３．Procedure

```console:Preparation
$ cd ~
$ sudo apt install qemu
$ mkdir qemu-debian-arm64;cd qemu-debian-arm64
$ curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=1z2mQO4nhHzX3MG2LESmJxpoESkCTN_8G" > /dev/null
$ CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"
$ curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=1z2mQO4nhHzX3MG2LESmJxpoESkCTN_8G" -o xenial-server-cloudimg-arm64-disk1.img
$ sudo chmod 777 xenial-server-cloudimg-arm64-disk1.img

$ sudo modprobe nbd max_part=63
$ sudo qemu-nbd -c /dev/nbd0 xenial-server-cloudimg-arm64-disk1.img
$ mkdir mnt
$ sudo mount /dev/nbd0p1 mnt
$ ls -lt mnt/boot

合計 53008
drwxr-xr-x 2 root root     4096  6月 18 07:58 grub
-rw-r--r-- 1 root root 35500697  6月 18 07:58 initrd.img-4.4.0-151-generic
lrwxrwxrwx 1 root root       28  6月 18 07:57 initrd.img -> initrd.img-4.4.0-151-generic
lrwxrwxrwx 1 root root       28  6月 18 07:57 initrd.img.old -> initrd.img-4.4.0-151-generic
lrwxrwxrwx 1 root root       25  6月 18 07:57 vmlinuz -> vmlinuz-4.4.0-151-generic
lrwxrwxrwx 1 root root       25  6月 18 07:57 vmlinuz.old -> vmlinuz-4.4.0-151-generic
-rw------- 1 root root  3659266  6月 11 19:08 System.map-4.4.0-151-generic
-rw-r--r-- 1 root root   178853  6月 11 19:08 config-4.4.0-151-generic
-rw------- 1 root root 14929920  6月 11 19:08 vmlinuz-4.4.0-151-generic

$ sudo cp mnt/boot/vmlinuz-4.4.0-151-generic .
$ sudo cp mnt/boot/initrd.img-4.4.0-151-generic .

$ sudo umount mnt
$ sudo qemu-nbd -d /dev/nbd0
/dev/nbd0 disconnected

$ sudo chmod 777 *-generic
```

```console:Start_virtual_machine
$ sudo qemu-img resize xenial-server-cloudimg-arm64-disk1.img +10G
$ qemu-system-aarch64 -m 8192 -cpu cortex-a53 -nographic -machine virt \
-kernel vmlinuz-4.4.0-151-generic \
-append 'root=/dev/vda1 rw rootwait mem=8192M console=ttyS0 \
 console=ttyAMA0,38400n8 init=/usr/lib/cloud-init/uncloud-init \
 ds=nocloud ubuntu-pass=ubuntu' \
-drive if=none,id=image,file=xenial-server-cloudimg-arm64-disk1.img \
-initrd initrd.img-4.4.0-151-generic \
-device virtio-blk-device,drive=image \
-netdev user,id=user0 \
-device virtio-net-device,netdev=user0
```

```console:Login
ubuntu login: ubuntu
Password: ubuntu
```

```console:Virtual_machine_shutdown
$ sudo shutdown -h now
```

# ４．Reference articles
**https://www.mztn.org/dragon/arm64_01.html**
**http://www.ne.jp/asahi/it/life/it/kvm/qemu/qemu_tips.html**
**https://blahcat.github.io/2018/01/07/building-a-debian-stretch-qemu-image-for-aarch64/**
【PHP】【MySQL】値をパラメータにバインドする時は名前付けされたプレースホルダよりも疑問符プレースホルダを用いた方が良いのか？

検索しやすいので名前付けプレースホルダを使ってSQLを書いていたのですが、「サポートしてないから疑問符プレースホルダを使ってほしい」と指摘が入りました。
…が、別に名前付けプレースホルダでも想定通りの結果が得られています。順序を変えても問題ありません。
今更、秀丸エディタで', 'を', :'で全置換して書いたSQLをすべて疑問符に書き換えるのは面倒臭くてそのままにしていたのですが、なぜこの指摘が入ったのか気になったので調べてみました。

# 結論
MySQLのバージョンが5.6系だから

## 教えて！Google先生
「php mysql bind 疑問符」でググったトップに出てくるteratailの回答がアンサーでした。

[MySQL - SQLで名前つきでない疑問符プレースホルダがよく使われるのはなぜでしょうか？｜teratail](https://teratail.com/questions/109351#reply-180873)
[MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.5.1 PREPARE 構文](https://dev.mysql.com/doc/refman/5.6/ja/prepare.html)

想定通りの結果を得られているけど、疑問符プレースホルダに書き換えるべきなのか…。
リモートワークに全然興味の無かった自分が5ヶ月間リモートワークやって感じたこと



## 目的
転職した会社にリモートワーク制度があり、半年間ほど制度を利用してたので実体験や感想などを書いてみようと。勤務先にリモートワーク制度があるけど利用したことのない方や、リモートワーク制度のある会社に転職したいと思っている方の参考になればと。


## なぜリモートワーク制度を利用しようと思ったか
以前は「リモートワーク？絶対自分はサボって仕事しないから、制度あってもやらないだろうな」と思ってました。
が、たまたま転職先にリモートワーク制度があり、人事部の人から制度利用を勧められたので試しにやってみようと考えた次第です。
「子供も産まれたし、リモートワークした方がいいシーンも出てくるだろう。なんかあったときに慌てて環境整備するのもアレだしな」とか言ってた記憶があります。

## リモートワーク制度の中身
#### 基本は週1日 
自宅で集中して作業した方がいいタスク量が週1日分ぐらいなのが理由です。これ以上増やすと会社で作業した方が能率が上がります。

#### 8:00〜17:00 勤務
　ある程度自由に勤務時間は選べますが、あまり遅いとダレるのと、仕事が終わった後に家族の時間を確保するために始業時間を早めにしています。

#### 作業場所は自宅オンリー
　私は自室オンリーです。近所にカフェやコワーキングスペースもありますが、特に必要と感じたことがないので行ったことがありません。

#### あえてスーツを着る・・・ときもある
　もちろんリモートワークなので服装は自由なのですが、仕事感を出すために敢えてスーツを着て作業するときもあります。
　一度着替えるのがめんどくさいという理由だけでパジャマで仕事したことがありますが、能率はひどいもんでした。
　パジャマで作業だけはしない方がいいです。

## メリット
#### 通勤時間が短縮される
　通勤に往復で3時間かかるので、それをゼロにできるのは非常にありがたいです。このメリットだけでもリモートワークをする意義はあります。
#### 家事を仕事の合間にできる
　仕事の合間や休憩時間に家事を手伝うことにより、YHP(嫁ヘイトポイント)を減らすことができます。
#### 時間帯を気にせず宅配便を受け取れる
　快適な amazon ライフをあなたに。
#### 筋トレができる ※
　目指せベンチ100kg! プロテインも飲み放題！
　※筋トレしないので妄想です。ごめんなさい・・・。

## デメリット
#### 体を動かさないのでダルくなる
　とにかく外に出ないし、体を動かさない生活になります。その結果、体がダルくなることもしばしば。
　通勤って実は結構いい運動になってたんだなと実感します。
　気がついたら散歩に行くようにはしてますが、いかんせん引きこもり体質なため、なかなかサボることも・・・。
#### 周りにすぐに相談できる人が居ない
　実装で困ったときや、仕様の認識合わせをするときに苦労します。
　会社だったらすぐに聞けるのですが、自宅だとチャットツールを使うのでレスポンスが遅れることが結構あります。　
#### 気をぬくとサボれる
　「リモートワークで一番大事なのが自己管理だ」とネットの記事で見たことがありましたが、正にその通りだと思いました。
　監視の目が一切無いので、サボろうと思えばいくらでもサボれてしまいます。
　ので、私は自宅でもスーツに着替えるとか、昼休みの時間はアラームで管理するなどの対策を取っています。

## 最後に
　リモートワーク制度利用前は、あまりリモートワークに良い印象を持ってなかったのですが、用法用量を守れば良い制度だなと思います。
　まだリモートワーク制度を利用したことのない人は是非体験してみてはいかがでしょうか。
AWSにおけるコンテナの管理

# コンテナとは
コンテナを使用すると、アプリケーションコード、構成、および依存関係を単一オブジェクトへパッケージ化ができます。サーバーにインストールされたオペレーティングシステムを共有し、リソースが分離したプロセスとして実行され、環境に関係なく、迅速で信頼性も高く、一貫性のあるデプロイを保証しています。
Dockerfile -> Docker imange -> Docker container

# ECS
Docker コンテナアプリケーションを AWS で簡単に実行、スケール、保護できます。
簡単な API コールを使用して、Docker 対応アプリケーションを管理できる。
リージョン内の複数のアベイラビリティーゾーン間で可用性の高い方法でアプリケーションコンテナを実行する。
・起動タイプにはFargateとEC2がある。
・アプリケーションの実行にはタスク定義が必要（タスク定義とはアプリケーションを構成する１つ以上のコンテナを記述するJSONファイル＝アプリケーションの設計図）
<img width="798" alt="スクリーンショット 2019-06-19 21.14.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178012/b496a6ac-fee5-d953-0539-8360301fd567.png">

・タスク - クラスター内のタスク定義のインスタンス化。
・スケジュール - クラスターへのタスク配置を管理。
・コンテナエージェント - ECSとタスクの仲介役


# Fargate
ECS をサーバーレスで利用できるようするサービス。
・
・

# EKS
コンテナのオーケストレーションサービスである kubernetes のラッパーサービス。
・
・
Railsのdate_selectメソッドのinclude_blankオプションで、今日の日付をデフォルト表示する方法

# はじめに
Railsでタスク管理アプリを作成した際に、タスクに終了期限を登録するために、deta_selectメソッドにinclude_blankオプションを利用しました。
その時に、ブランクがデフォルトで表示されてしまい困ったので、解決方法を書きたいと思います。

# 前提
前提条件として、私が利用したRubyとRailsのバージョンは以下の通りです。

```ruby
ruby '2.5.0'
rails '5.2.3'
```

# 再現
今回はすぐに確認できるよう`rails genererate scaffold`で簡易的にタスク管理機能を実装します。

```ruby
rails generate scaffold task title:index limit:date

rails db:migrate
```

上記のコマンドを実行すると、タスクのコントローラー、モデル、ビューが良い感じに設定されると思います。
formを確認すると、次のようになっています。


```erb:views/tasks/_form.html.erb
<div class="field">
  <%= form.label :limit %>
  <%= form.date_select :limit %>
</div>
```

<img width="848" alt="limit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344685/f1409a71-26b7-6e82-c22f-74c22397cae7.png">

しかし、終了期限は入力必須ではないので、`include_blank`オプションで、ブランクを入れられるように設定します。

```erb:views/tasks/_form.html.erb
<div class="field">
  <%= form.label :limit %>
  <%= form.date_select :limit, include_blank: true %>
</div>
```

<img width="842" alt="blank.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344685/7434f3aa-3f53-f158-eb68-53f3ea9e231a.png">
うーん、ブランクがデフォルトで選択されてしまっている。この状態から年月日を選択するのは面倒だな・・・。
ブランクを使えるようにしつつ、今日の日付がデフォルトで選択されるようにしたいな・・・。

# 解決策
`selected`オプションに`Date.today`を設定することで、ブランクを残しつつ、今日の日付がデフォルトで選択されるようになります。

```erb
<%= form.label :limit %>
<%= form.date_select :limit, include_blank: true, selected: Date.today %>
```

<img width="848" alt="limit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344685/260cd6c3-1d34-1e69-a710-a5bd4ad70440.png">
以上です！