OmniAICreator/Qiita-1.07M huggingface dataset:
RxWebKitを使ってWKWebViewのローディング処理（プログレスバー更新等）をイイ感じにする

# 概要

- `RxWebKit` というライブラリを使って、WKWebViewのローディング処理のUI更新周りをイイ感じに書く方法を紹介
- [RxSwiftを使ってWKWebViewのローディング処理をイイ感じにする](https://qiita.com/k0uhashi/items/1b2913422aea0af28d56)の記事の続き

# イメージ

![rxwebkit.gif](https://qiita-image-store.s3.amazonaws.com/0/126441/391b4d4a-1f0e-13f3-45aa-bc86b866efbd.gif)


# リポジトリ

- 公式
    - [https://github.com/RxSwiftCommunity/RxWebKit](https://github.com/RxSwiftCommunity/RxWebKit)
- サンプル
    - [https://github.com/ryo-takahashi/WKWebViewRxSwiftLoadingExample](https://github.com/ryo-takahashi/WKWebViewRxSwiftLoadingExample)

# 環境

- Xcode 9.4
- Swift 4.1
- RxSwift 4.2
- RxCocoa 4.2
- RxOptional 3.5.0

# 環境構築

```ruby:Podfile
  pod 'RxSwift'
  pod 'RxCocoa'
  pod 'RxOptional'
  pod 'RxWebKit'
```

# 画面

![スクリーンショット 2018-08-21 19.43.27.png](https://qiita-image-store.s3.amazonaws.com/0/126441/a287acd5-f83a-3c33-3ba9-8f08a2f02b69.png)

- 画面構成
    - WKWebView
    - Progress View

# コード

```swift

import UIKit
import WebKit
import RxSwift
import RxCocoa
import RxOptional
import RxWebKit

class RxWebkitViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var progressView: UIProgressView!
    
    private let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupWebView()
    }
    
    private func setupWebView() {
        
        // プログレスバーの表示制御、ゲージ制御、アクティビティインジケータ表示制御で使うため、一旦オブザーバを定義
        let loadingObservable = webView.rx.loading
            .share()
        
        // プログレスバーの表示・非表示
        loadingObservable
            .map { return !$0 }
            .observeOn(MainScheduler.instance)
            .bind(to: progressView.rx.isHidden)
            .disposed(by: disposeBag)
        
        // iPhoneの上部の時計のところのバーの（名称不明）アクティビティインジケータ表示制御
        loadingObservable
            .bind(to: UIApplication.shared.rx.isNetworkActivityIndicatorVisible)
            .disposed(by: disposeBag)
        
        // NavigationControllerのタイトル表示
        webView.rx.title
            .filterNil()
            .observeOn(MainScheduler.instance)
            .bind(to: navigationItem.rx.title)
            .disposed(by: disposeBag)
        
        // プログレスバーのゲージ制御
        webView.rx.estimatedProgress
            .map { return Float($0) }
            .observeOn(MainScheduler.instance)
            .bind(to: progressView.rx.progress)
            .disposed(by: disposeBag)
        
        
        let url = URL(string: "https://www.google.com/")
        let urlRequest = URLRequest(url: url!)
        webView.load(urlRequest)
    }
}
```

- 良い
    - 完全にタイポの可能性がなくなった
        - コンパイルエラーで発見できる
    - 直感的に書ける、わかる
        - `webView.rx.title` のところ、navigationItemのtitleにbindしてるんだなーというのがすぐわかる

# まとめ

- `RxWebKit` を使うことでわかりやすくUIの処理ができるようになった

# Notes

- 今回は紹介していませんが、`RxWebKit` には `canGoBack` `canGoForward` などもっと色々なパラメータがあります
- 詳しくは [https://github.com/RxSwiftCommunity/RxWebKit](https://github.com/RxSwiftCommunity/RxWebKit)
Analytical network processes（サービスサイエンスの事はじめ　高木英明先生　筑波大学出版会）

```{r}

#ANP

library(dplyr)

D1=t(matrix(c(1,5,1/5,1),ncol=2,nrow=2))

D2=t(matrix(c(1,1/3,3,1),ncol=2,nrow=2))

D3=t(matrix(c(1,1/7,7,1),ncol=2,nrow=2))

v1=eigen_vector_D1=sqrt(apply(D1,1,prod))/sum(sqrt(apply(D1,1,prod)))

v2=eigen_vector_D2=sqrt(apply(D2,1,prod))/sum(sqrt(apply(D2,1,prod)))

v3=eigen_vector_D3=sqrt(apply(D3,1,prod))/sum(sqrt(apply(D3,1,prod)))

D_bar=t(matrix(c(1,9,3,1/9,1,1/5,1/3,5,1),nrow=3,ncol=3))

w1=(apply(D_bar,1,prod)^(1/ncol(D_bar)))/sum(apply(D_bar,1,prod)^(1/ncol(D_bar)))

mat1=matrix(c(1,1,1,1,1,1,1,1,1),nrow=3,ncol=3) 

mat2=t(matrix(c(1,1/3,1,3,1,3,1,1/3,1),nrow=3,ncol=3)) 

mat=(mat1^(16/22))*(mat2^(6/22))

w2=(apply(mat,1,prod)^(1/ncol(mat)))/sum(apply(mat,1,prod)^(1/ncol(mat)))

w=cbind(w1,w2);v=cbind(v1,v2,v3)

wv=w%*%v

wv_eigen_values=eigen(wv)$values

wv_eigen_vectors=eigen(wv)$vectors

q=wv_eigen_vectors[,1]/sum(wv_eigen_vectors[,1])

p=v%*%q



#super_matrix(5.12)

super_matrix=array(0,dim=c(5,5))

super_matrix[3:5,1:2]=w

super_matrix[1:2,3:5]=v

#(5.8)

A=matrix(rep(0,6*6),ncol=6,nrow=6)

A[1,1]=1
A[2:3,1]=v1
A[4:6,2:3]=w

#Frobenius theorem

max_eigen=max(eigen(A)$values)

p=rep(0,nrow(A))

p[1]=A[1,1]

for(i in 2:nrow(A)){
  
p[i]=sum(A[i,1:(i-1)]*p[1:(i-1)])/(max_eigen-A[i,i])  
  
}


eigen_vector=eigen(super_matrix)$vectors[,1]

p=eigen_vector[1:2]/sum(eigen_vector[1:2])

q=eigen_vector[3:5]/sum(eigen_vector[3:5])

```
Shellメモ

#Shell
bashで使ってます。

##alias
構文）
```alias <名前>=<command>```
注意）
この時"="の横にスペースを入れるとエラーになります。可読性？はて？、Editorが色付けしてくれるから問題ないです。

ex)
```alias ls='rm -rf　.'```
これはなんと最悪のaliasでしょう！　怒りがこみ上げて来そうですね。
ちなみに、引数をつけたりする際はクォーテーションで囲みましょう。


このように
aliasコマンドを使うと、別名を定義することができます。
イカしたワンライナーを作って使いやすい名前をつけておけば色々と捗りますね。

**aliasの内容を表示したい時！**
自分で作ったalias、他人が作ったalias、わざわざ定義を探して見るのも面倒だす。
そんな時でもすぐaliasの内容を表示できるのでご安心。
次のコマンド一発で表示
```alias <aliasに設定した名前>```
これでaliasの内容を表示します。

ターミナルで、aliasコマンドの引数にalias設定した名前を引数にするとそのaliasの内容が出てくるんですね。

##awk
```echo aaa bbb | awk '{print $2}'```
もっと複雑なことをやります。

##uniq

##sed
```sed 's/^s_/S_/g'```
もっと複雑なことをやります

##sort
```sort <ファイル名>```
うーパイプでつないだりする
```grep namuamidabutsu | sort ```

sortしてuniqするのが多いかもしれない
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - 12.6 1次元の空間構造

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import numpy as np
import pandas as pd
import pystan
import matplotlib.pyplot as plt
from matplotlib.figure import figaspect
%matplotlib inline
```

### データ読み込み

```python
kubo11a = pd.read_csv('./data/data-kubo11a.txt')
```

# 12.6 1次元の空間構造

```python
data = dict(
    I=kubo11a.index.size,
    Y=kubo11a['Y']
)
stanmodel = pystan.StanModel('./stan/model12-11.stan')
fit = stanmodel.sampling(data=data, seed=1234)
stanmodel_b = pystan.StanModel('./stan/model12-12.stan')
fit_b = stanmodel_b.sampling(data=data, iter=4000, seed=1234)
```

```python
probs = (10, 25, 50, 75, 90)
columns = ['p{}'.format(p) for p in probs]
_, axes = plt.subplots(1, 2, figsize=figaspect(3/8), sharex=True, sharey=True)

for i, f in enumerate([fit, fit_b]):
    ax = axes[i]
    ms = f.extract()
    
    d_est = pd.DataFrame(np.percentile(ms['Y_mean'], probs, axis=0).T, columns=columns)
    d_est['x'] = d_est.index + 1
    
    ax.plot('x', columns[2], data=d_est, color='k')
    for j in range(2):
        ax.fill_between('x', columns[j], columns[-j-1], data=d_est, color='k', alpha=0.2*(j+1))
    ax.scatter(kubo11a.index+1, kubo11a['Y'], facecolor='w', edgecolor='k')
    plt.setp(ax, xlabel='i', ylabel='Y[i]')

plt.show()
```
![fig12-7.png](https://qiita-image-store.s3.amazonaws.com/0/103085/4f5b99e0-f1bb-dbea-7444-f8c93db26fe7.png)
LPICに申し込む方法について走り書き（※Linucではない）

##LPIC1(101)に申し込みました
世間では「Linucに移行してLPICが終わる！」みたいな論調の記事がありますが、これまで通り、LPICは日本国内でも受験可能です。
（ただしLinucの申し込みと違ってちょっとわかりづらいです。）

LinucとLPICの違いは[前の記事](https://qiita.com/Alpha_Nine/items/15e4eb478166fcf9008d)参照






##LPI-ID をLPI日本支部から取得
- LPI日本支部登録ページ

https://cs.lpi.org/caf/Xamman/register

個人情報を入力して登録。
英語ベースなんで住所入力が独特、打ち間違いに注意。
登録完了後、LPI-IDが表示されるので、メモしておく


##ピアソンビューに登録

- ピアソンビューLPIC申し込みページ

https://www.pearsonvue.co.jp/Clients/LPI.aspx

アカウントを持ってなければ、「アカウント作成」からアカウントを作る。
※ここで上記のLPI-IDを使用。

ローマ字入力なので注意。
FirstName（名前） と LastName（苗字） だけ入れればOK
（…ミドルネームとかサフィックスとか無ければ）

こちらも住所は英語ベース。しかもこちらは全角不可（英字制限）

最後に日本語で住所の登録。英字での登録とは一体


##ピアソンビューにログインして登録
ログイン後、ホームに表示されている
「試験を表示」
をクリック。試験が選択できるようになるので、受験科目を選択。
※あんま聞きなれないLPIC1以下の資格もできたようなので、科目選択に注意してください。

自分は101を申し込みたいので
「 LPI Level 1 Exam 101, Junior Level Linux Certification, Part 1 of 2」
を選択しました。

LPI日本支部（LPI-Japanではない）
のサイトからでもバウチャーは買えるそうですが（2018/08/21現在で$134だった）
めんどくさそうのでピアソンビューで購入（カード決済）。

近くの受験会場、受験日を選択して申し込み完了、正しく申し込めてればメールが届きます。

8/31（金）に受験してきます！頑張るよ！٩( 'ω' )و
配列の要素の削除

##先頭の要素を削除 .shift()

```js
const arr = [1,2,3,4,5];
arr.shift();
console.log(arr); // [2,3,4,5]
```

##末尾の要素を削除 .pop()
```js
const arr = [1,2,3,4,5];
arr.pop();
console.log(arr); // [1,2,3,4]
```

##任意の位置の要素を削除 .splice()
```js
const arr = [1,2,3,4,5];
arr.splice(2); //2番目以降の要素を削除
console.log(arr); //[1,2]

const arr2 = [1,2,3,4,5];
arr2.splice(1,3); //1番目から3個の要素を削除
console.log(arr2); //[1,5]

const arr3 = [1,2,3,4,5];
arr3.splice(2,1); //2番目から1個の要素を削除
console.log(arr3); //[1,2,4,5]
```
2つめの引数は場所ではなく要素の個数なので注意。

.splice()には要素の置換/追加機能もあるが
ひとまず削除する場合だけ。
Rails tutorial 8 章　エラー「 jQuery  を導入できない。」


jQuery を、チュートリアルのように、

//= require rails-ujs
//= require jquery
//= require bootstrap
//= require turbolinks
//= require_tree .


app/javascript/application.js 
に書き込んだら、


<img width="1144" alt="スクリーンショット 2018-08-21 18.16.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/232715/a2c560f8-db3e-fc63-4115-0f4dab9d6d98.png">




jquery 見つからないよ！　って怒られました。
このエラーにハマったので、解決法を記します。


Gemfile に、

gem 'jquery-rails', '4.3.1'


を追加して、bundle install するだけでした。。

以上です。皆様の参考になれば幸いです。
javascript concat(), const


참고 https://msdn.microsoft.com

## const의 사용 예
```javascript:qiita.rb
var c = 10;
{
    const c = 2;
   // At this point, c = 2.
}
// At this point, c = 10.

// Additional ways to declare a variable using const.
const name = "Thomas Jefferson";
const answer = 42, numpages = 10;
const myarray = new Array();
```

## concat()은 배열을 조합한다
```javascript:qiita.rb
var a, b, c, d;
a = new Array(1,2,3);
b = "dog";
c = new Array(42, "cat");
d = a.concat(b, c);
document.write(d);

//Output: 
1, 2, 3, "dog", 42, "cat"

```
Rails Controller で layout を複数呼び出す

## Rails Controller で `layout` を複数呼び出すと後勝ちで上書きされる

### 例

```ruby:some_controller.rb
class SomeController < ApplicationController
  layout 'layout_for_index', only: :index
  layout 'layout_for_show', only: :show

  def index; end
  def show; end
end
```
### 結果

- `some#index` -> デフォルトの layout が適用される
- `some#show` -> `layout_for_show` が適用される

## `layout` にはメソッド名やprocを渡せるのでこんな感じで書けばいける

```ruby:some_controller.rb
  layout :determine_layout
  ...
  def determine_layout
    case action_name
    when 'index' then 'layout_for_index'
    when 'show' then 'layout_for_show'
    end
  end
```

## 該当コード見ると普通に代入してるので当然の動きですね

```ruby:rails/actionview/lib/action_view/layouts.rb:267
def layout(layout, conditions = {})
  include LayoutConditions unless conditions.empty?

  conditions.each { |k, v| conditions[k] = Array(v).map(&:to_s) }
  self._layout_conditions = conditions

  self._layout = layout
  _write_layout_method
end
```

source: [rails/actionview/lib/action_view/layouts.rb:267](https://github.com/rails/rails/blob/fc5dd0b85189811062c85520fd70de8389b55aeb/actionview/lib/action_view/layouts.rb#L267)
WindowsPowershellにおけるMACのopenコマンド

Powershellは

```:powershell
Invoke-Item
```

Macは

```:mac
open
```

参考
https://technet.microsoft.com/ja-jp/library/ee176882.aspx
http://macwiki.osdn.jp/wiki/index.php/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/open
pathlibのメソッドチェーンだけでパスを加工したい

<a href="https://teratail.com/questions/141682">フルパスを持つPath or strから、任意に指定した階層以上だけを切り捨てたい</a>
という質問をさせてもらって、「partsってなんだ？」ってなったんで徹底的に調べてみました。
この場を借りまして、改めてご回答いただいた皆さんに御礼申し上げます。

# partsについて
<a href="https://docs.python.jp/3/library/pathlib.html#accessing-individual-parts">公式ドキュメント：parts</a>に書いていますが、ちゃんと調査をしてみます。

.parts[-1:]
　　.name(basename)を取得したい
.parts[[:-1]
　　parent,parents[]を取得したい
.parts[[1:-1]
　　上から指定のパスを消し、下から指定のパスを消したい
.parts[[:1]
　　上から順番にパスを取得したい
.parts[[1:]
　　上から順番にパスを消したい

というようになるみたいです。
ややこしくて理解するのが大変でした。

# 視覚化したい！
色々やったんですが視覚的な情報（表とか）を作るのはブログの方が楽だったんで、そちらに移してます。
ご参考程度に。
<a href="https://nomuraya.work/develop/037">parts: parentやparents、nameのラップ元であり現在のパスの操作をもっと拡張したい</a>

# 読了後いいね！をお願いします。
どれだけの方に読んでもらっているか知りたいので、お手数をおかけしますがご協力いただけると嬉しいです。
ChefとAnsibleにおけるファイル作成の比較

ChefとAnsibleで、内容を指定したファイル作成を比較してみる。
/tmp/text.txtファイルに"foo\n"を設定する。
対象システムはUnix or Linux


#Chef 例

fileリソースのcontent属性を使用する

```ruby
file '/tmp/text.txt' do
  content "foo\n"
end
```

- 必要にして十分。
- ファイルを扱う専用リソースなので、他にも、オーナー、グループ、権限、バックアップなどに対応。


#Ansible 例

```yaml
---
- hosts: all
  tasks:

  - copy:
      content: |
        foo
      dest: /tmp/text.txt
```

- copyモジュールにファイルの内容を設定する機能あったので例を更新。(2019/03)

参考
[copy – Copies files to remote locations](https://docs.ansible.com/ansible/latest/modules/copy_module.html)

#蛇足 InSpec の例

Ruby DSLなのでChef like
ServerSpecでも同様という理解。

```ruby
describe file('/tmp/test.txt') do
  its('content') { should eq "foo\n" }
end
```
LocalAuthenticationに関する覚え書き

FaceID/TouchIDでの認証を実装した際に，ちょこちょこつまづいた点があったので記録．

# 基本

## 生体認証の利用可否をチェック
```Swift
func checkIfBiometricAuthenticationAvailable() -> Bool {
    let context = LAContext()
    var error: NSError?
        
    // 生体認証の利用可否チェック
    let isAvailable = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)

    // MEMO: iOS11以降は認証方式を判別可
    let type: BiometricAuthenticationType
    if #available(iOS 11.0, *) {
        switch context.biometryType {
            case .faceID:
                print("FaceID")

            case .touchID:
                print("TouchID")

            case .none:
                break
    }

    if let e = error else {
        // Error handling…
        print(e)
    }

    return isAvailable
}
```

## 生体認証の実行
```Swift
func authenticate() {
    let context = LAContext()
    let reason = "TouchID でロックを解除"
    context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { (success, error) in
        guard error == nil else {
            // Error handling…
            return 
        }     

        if success {
            // 認証成功
        } else {
            // 認証失敗
        }
    }
}
```

# つまづいた点
## `LABiometryType`の取得
取得できるのは`LAContext.canEvaluatePolicy()`実行後のみ．
仕様なので仕方はないが，生体認証方式を知るにも多少手数がかかるのでなんとも言えない気持ちになる．

  - [公式ドキュメント](https://developer.apple.com/documentation/localauthentication/lacontext/2867583-biometrytype)．


## 生体認証方式の判定
標準で用意されている `LABiometryType` もあるが，多少冗長でも独自のEnumを使った方が良さげ．

### 理由
1. 利用可能なOSバージョン
  - `LABiometryType` はiOS11.0 ~ のため，それ以前のOSをサポートしている場合，ラップしておいた方が楽
2. FaceIDのアクセス不許可時もまとめてハンドリングできる
    - FaceID対応端末の場合，生体認証のアクセス許可を変更できる．そのため，FaceID対応端末については許可状態もまとめて管理できるようにすると，より細やかな出し分けができる
      - e.g. 設定画面においてFaceID/TouchIDでラベル・アイコンの出し分けを行い，かつFaceIDのアクセスが許可されていない場合にメッセージを表示する場合

### 実装例
```Swift
enum BiometricAuthenticationType {
    case faceID(permitted: Bool)  // FaceID端末は設定アプリ上でアクセスを不許可にできるので許可状態も把握できるようにしておく
    case touchID  // TouchID端末はアクセス許可を変更できないので種別のみ判定できればOK
    case none
}
```

## 認証に使用する`LAContext`
一度認証に成功すると `evaluatePolicy` の結果は常にtrueを返すので都度生成する必要がある．

## `LAContext.canEvaluatePolicy`のエラーコード
iOS11 とそれ以前とで違うので， iOS10以前もサポートしている場合に `生体認証の利用が許可されていない` ケースをハンドリングする場合は以下のようにする必要がある．

```Swift
var error: NSError?       
let isAvailable = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)

// 生体認証の利用が許可されていない場合に返ってくるエラーコード
let biometricAuthenticationNotAvailableErrorCode: Int
                
if #available(iOS 11.0, *) {
    biometricAuthenticationNotAvailableErrorCode = LAError.biometryNotAvailable.rawValue
} else {
   biometricAuthenticationNotAvailableErrorCode = LAError.touchIDNotAvailable.rawValue
}
                
if error?.code == biometricAuthenticationNotAvailableErrorCode {
    // 生体認証の利用が許可されていない場合の処理
}

…
```

## `LAContext.evaluatePolicy()` の `localizedReason`
空文字を指定するとクラッシュする．

- 空文字にしなければいいだけだが，ローカライズのキーだけ設定して英語の.stringsファイルは暫定的に空文字にしていたらクラッシュしてハマった．

# 雑感
iOS10以前をサポートしなければ，ここで書いたことの半分くらいは気にしなくても済むので，早くサポートを切りたい．

# おまけ
[Gist](https://gist.github.com/gaussbeam/666484767c5c09c551065e278cbe3900)にまとめました．
配列のコピー

##配列の要素が文字列や数値の場合
.slice() もしくは.concat()で元の配列から値をコピーできる
→参照ではないので加工しても元の配列に影響しない

```js
const arr = [1,2,3,4,5];
const arrCopy = arr.slice(); 
arrCopy[0] = 6;
console.log(arr); // 1,2,3,4,5
console.log(arrCopy); // 6,2,3,4,5

const arr2 = ['A','B','C'];
const arrCopy2 = arr2.concat(); 
arrCopy2[2] = `Z`;
console.log(arr2); // A,B,C
console.log(arrCopy2); // A,B,Z
```

##配列の要素がオブジェクトの場合
.slice() や.concat()ではオブジェクトは参照コピーになってしまう。

```js
const arr = [
{id:'a'},
{id:'b'}
];
const arrCopy = arr.slice(); 
arrCopy[0].id = 'z';
console.log(arr[0]); // {id:'z'}
console.log(arrCopy[0]); // {id:'z'}
```
元の配列まで変更されてしまった！

##配列の要素がオブジェクトの場合、コピーには.map()を使う

```js
const arr = [
{id:'a'},
{id:'b'}
];
const arrCopy = arr.map(arr => ({id:arr.id}));
arrCopy[0].id = 'z';
console.log(arr[0]); // {id:'a'}
console.log(arrCopy[0]); // {id:'z'}
```
元の配列はそのまま！やったー


##以下メモ
###.map()
配列.map((引数) => {配列内の要素を加工するコールバック関数});

・引数には配列の要素の値が入る
・配列内の要素が1つずつ関数で加工され新しい配列が生成される
・returnで戻り値を返す必要がある

上記の例の場合、変数arrの各要素はオブジェクトなので
引数arrには各オブジェクト　{id:'a'}、{id:'b'}　が入る
コールバック関数で新たにオブジェクトを生成し、引数arrのidをセット
({id:arr.id})　
後述、アロー関数で記述しているのでreturnは省略。

###アロー関数
(引数) => {関数}が基本形で
引数が1つの場合()が、関数も一行の場合{}が省略できる
関数の{}を省略する際はreturnも省略可
引数 => 関数

ただし関数にオブジェクトが入る場合、
関数を囲む{}とオブジェクトリテラルの{}が区別できず
エラーとなってしまうため()で囲む必要がある
引数 => ({オブジェクト})
GCP Stackdriver LoggingをLaravelで使う

## 参考URL

 - https://cloud.google.com/logging/


## サービスアカウント作成

'IAMと管理 > サービスアカウント' 画面で新しくサービスアカウントを作成し、Credential jsonファイルを作成する。

## ライブラリインストール

```
composer require google/cloud-logging
```

## ログ出力

Globalではなく、対象インスタンスでのログとして保存できるようにする。

``` php
$logger = LoggingClient::psrBatchLogger('app', [
    'resource' => [
        'type' => 'gce_instance',
        'labels' => [
            'instance_id' => "69787982158********",// 対象インスタンスでのログとして保存
        ]
    ],
    'clientConfig' => [
        'keyFilePath' => base_path('gcp_credentials.json'),// サービスアカウント作成時の認証情報jsonファイル
    ]
]);

$logger->info("hoge");
```

## 確認

「Logging > Logs」画面で確認可能、このとき「GCS VM Instance」で対象のインスタンスでフィルターを掛ける。

## アラート通知

### Stackdriver Logging Agentをインストール

対象のインスタンスにログインして下記コマンド実行

```
curl -sSO https://dl.google.com/cloudagents/install-logging-agent.sh
sudo bash install-logging-agent.sh
```

### Logs-based metrics作成

「Logging > Logs-based metrics」画面の「CREATE METRIC」をクリック
下記のようにSeverityがERRORのログを集めるように設定します。

参考URL:　https://cloud.google.com/logging/docs/logs-based-metrics/counter-metrics

<img width="393" alt="スクリーンショット 2018-08-21 20.33.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/56193/78a8951b-3ce0-538b-a859-4575800389f8.png">



### Alert Policy作成

[Stackdriver](https://app.google.stackdriver.com/policy-advanced)の「Alerting」画面へ行き
「Add Policy」をクリック、`Condition`には`Metric Conditions`を選択し
先程作ったオリジナルのLogs-based metrics`logging/user/Error`をMetricとして選択。

<img width="396" alt="スクリーンショット 2018-08-21 19.20.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/56193/25e4f22a-1b99-7eed-1b7d-d6d264ad69c5.png">
ESLint v5.4.0

前 [v5.3.0] | 次 (2018/09/01 JST)

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">ESLint v5.4.0 has been released: <a href="https://t.co/z82KAdWF3b">https://t.co/z82KAdWF3b</a></p>&mdash; ESLint (@geteslint) <a href="https://twitter.com/geteslint/status/1030619952888336385?ref_src=twsrc%5Etfw">August 18, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ESLint 5.4.0 がリリースされました。
エラーメッセージの改善等が行われました。機能追加はありません。

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

> 🏢 [日本語 Issue 管理リポジトリ](https://github.com/eslint/eslint-jp)
> 👫 [日本語サポート チャット](https://gitter.im/eslint/eslint-jp)
> 🏢 [本家リポジトリ](https://github.com/eslint/eslint)
> 👫 [本家サポート チャット](https://gitter.im/eslint/eslint)

<!--
# 🚀 本体への機能追加

特になし。

# 💡 新しいルール

特になし。

# 🔧 オプションが追加されたルール

特になし。

# ✒️ `eslint --fix` をサポートしたルール

特になし。

# ⚠️ 非推奨になったルール

特になし。
-->

[v5.3.0]: http://qiita.com/mysticatea/items/eb99e18d6cc7c3bf9317
[#9999]: https://github.com/eslint/eslint/issues/9999
[xxxx]: http://eslint.org/docs/rules/xxxx

<!-- 
![JSCS Icon](http://jscs.info/favicon.ico) JSCS 互換ルールです。
-->
デプロイしたCloud Functionsが更新されない問題をどうにかする

[GCPのCloud Buildを試してみた](https://qiita.com/fumihiko-hidaka/items/ac60b920155c31b61eaf)

上の記事で一度デプロイしたCloud Functionsが更新されない！　という問題にぶつかったので。
別記事として備忘録も兼ねて。

# 更新されないCloud Functions

構成としてはこんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/0c5acdfb-f595-b8a8-72d9-dc8209c445e8.png)

シンプル！ 

# 更新されない項目

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/1c8a98a3-2126-f5e7-ce3e-f2be40091914.png)

（今は問題が解決したので更新されていますが）
ソースを変更したpushをしても、この部分が更新されない！

# 解決方法

```bash
gcloud beta functions deploy cloud-build-notification \
  --runtime nodejs8 \
  --region asia-northeast1 \
  --project neko-tech-test \
  --source https://source.developers.google.com/projects/neko-tech-test/repos/cloud-build-sample/moveable-aliases/master/paths/cloud_function/ \
  --entry-point notification \
  --trigger-resource cloud-builds \
  --trigger-event google.pubsub.topic.publish
```

更新しなおしたよ、ということをコマンドを叩いて教えてあげる必要がありました。
自分の場合は、Cloud Source Repositoriesを使用していたので、sourceの指定が割と長い感じになっています。
httpをトリガーにしている場合は、trigger-resourceやeventではなく、trigger-httpを設定してあげましょう。

## 環境変数について
Cloud Functionsでは関数ごとに環境変数を登録することができます。
再更新の際にも環境変数を設定してあげないと消えてしまいそうな気がするんですが……ちゃんと、消えません！

https://cloud.google.com/sdk/gcloud/reference/beta/functions/deploy

clear-env-vars, env-vars-file, set-env-vars, remove-env-vars, update-env-vars

と、上記の引数がコマンドで設定可能なんですが、
逆に何も指定しなければ設定してある環境変数はそのままでした！


# 最後に

[株式会社ネコカリ](https://www.nekokari.co.jp/)では猫の手も借りたい🔥炎上中🔥なお仕事を募集しています！
サーバレスでもなんでもウェルカム。
一緒に働くメンバーも募集していますので、よかったら是非！
Ginでリクエストボディをstringで受け取る

リクエストボディを構造体にマッピングする以前に、どんなリクエストが来ているのか知るためにstringで見たいときがある。

```go
package main

import (
        "fmt"
        "github.com/gin-gonic/gin"
)

func main() {
        router := gin.New()

        router.POST("hoge", func(c *gin.Context) {
                buf := make([]byte, 2048)
                n, _ := c.Request.Body.Read(buf)
                b := string(buf[0:n])
                fmt.Println(b)

                c.Status(200)
        })

        router.Run()
}
```
https://github.com/gin-gonic/gin/issues/1295#issuecomment-380631496

なお上のコードだと `c.Request.Body` のストリームを読み切ってしまうので、それがいやならば以下の記事のようにストリームに対してデータを書き戻すような実装をする必要がある。

https://qiita.com/IzumiSy/items/e9bafb122c8cfab72361
Rails：HTTPとRESTfulなリソース設計について

HTTPとRESTfulなリソース設計についてまとめました。よろしくお願いいたします:bow_tone3:





前提...RailsにはHTTPリクエストからRubyの処理を呼び出し、クライアントに結果を返す仕組みが備わっている。
#HTTPとは
Hyper Text Transfer Protocol　の略で、分散コンピュータ間でHTMLなどの情報をやり取りするためのプロトコル
クライアントがサーバ上の「何かの情報」を「どうして欲しい」とリクエスト（HTTPリクエストという）し、サーバがレスポンスする

「何かの情報」→クエリとパス
「どうして欲しい」→HTTPメソッド

##HTTPメソッドとは
クライアントが行いたい処理をサーバに伝える手段

よく使う4つのメソッド↓
**GET**..リソースを取得する
**POST**..サーバー上にリソースを作成する
**PUT**..リソースの状態を変更、または更新する
**DELETE**..リソースを除去、または削除する
##CRUDとは
システムに必要な4つの主要機能である**「生成（Create）」「読み取り（Read）」「更新（Update）」「削除（Delete）」**のイニシャルを並べた用語のこと






#RESTとは
インターネット（Web）上でいろいろな情報や機能を結びつける方法、あるいは考え方のひとつ。  
インターネット上にある情報やデータ（リソース）は、すべて固有の名前（URN）か固有の住所（URL）を持っている。この URN と URL を合わせて URI という。
そして、URI を指定することでリソースにアクセスし、そのリソースに対してHTTPメソッド（「GET」や「POST」など）を送ることで操作するという考え方


REST では明示的に HTTP メソッドを使う必要があり、しかも HTTP プロトコルの定義どおりの方法で使う必要があるので基本的な設計原則によって、**CRUD (create、read、update、delete)** 操作と**HTTPメソッド**とが 1 対 1 に対応付けられる


| HTTPメソッド     |  意味　 |    CRUD   |
|:-----------------|------------------:|:------------------:|
| POST/PUT             |作成　 |Create         | 
|   GET      |  読み込み |       Read      |
|       PUT       |        更新　 |           Update    |
|         DELETE    |削除　 |           Delete      |




#RESTfulとは
RESTの原則に従って実装されているシステムのこと
Webに運用したソフトウェア設計様式を備えたルート(REST)のことで、URLで表現することができる。
つまりURLに対してHTTPのメソッドを利用することで統一感のある、意味がつかみやすいURLを設計することができる。





ex)リソース対象として仮のモデルクラス(Product)を作成し、次にルート定義、最後にルートの確認を行う

```route.rb
resources :product
#productはリソース名
#リソース名はプログラムが使用するデータの一覧取得や編集などを行う対象となるものを設定する
```
ターミナルでモデルを作る　

```
$ rails g model product
```

を入力すると

```
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 Prefix Verb   URI Pattern                                                                              Controller#Action
                puroducts GET    /puroducts(.:format)                                                                     puroducts#index
                          POST   /puroducts(.:format)                                                                     puroducts#create
             new_puroduct GET    /puroducts/new(.:format)                                                                 puroducts#new
            edit_puroduct GET    /puroducts/:id/edit(.:format)                                                            puroducts#edit
                 puroduct GET    /puroducts/:id(.:format)                                                                 puroducts#show
                          PATCH  /puroducts/:id(.:format)                                                                 puroducts#update
                          PUT    /puroducts/:id(.:format)                                                                 puroducts#update
                          DELETE /puroducts/:id(.:format)                                                                 puroducts#destroy

```

resourcesメソッドを利用することでHTTPメソッド(Verb列）とURLとアクションが紐づいたルート定義が生成されていることがわかる
C＃でWord文書にテキストと画像の透かしを追加する

透かしは、会社のウェブサイトのロゴやテキストなど、オリジナルのワードドキュメントにいくつかのユニークなコンテンツを追加して、そのドキュメントが著作権で保護されており、自由に使用できないことを他人に思い出させることを指します。
私たちのよく使われるウォーターマークは、イメージウォーターマークとテキストウォーターマークです。 この資料では、[Spire.Doc](https://www.e-iceblue.com/Introduce/word-for-net-introduce.html)を使用してWordの文書に画像の透かしまたはテキストの透かしを追加する方法について詳しく説明します。

**画像の透かしを追加**
[C#]

```ruby:Program.cs
 

            //新しい単語文書オブジェクトを作成し、透かしを入れる必要がある単語文書をロードする
            Document document = new Document();
            document.LoadFromFile("テスト.docx");
            //新しい画像透かしオブジェクトを作成し、画像を追加する
            PictureWatermark picture = new PictureWatermark();
            picture.Picture = System.Drawing.Image.FromFile("ピクチャ.jpg");
            //画像のサイズを設定し、それをウォーターマークとして設定する
            picture.Scaling = 100;
            picture.IsWashout = false;
            document.Watermark = picture;
            //ドキュメントを保存
            document.SaveToFile("画像の透かし.docx", FileFormat.Docx2010);

```

イメージウォーターマークレンダリング
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/278784/7e609b65-7f22-97b4-9717-5294f60c358f.jpeg)



**テキストの透かしを追加**
[C#]

```ruby:Program.cs

            //新しい単語文書オブジェクトを作成し、透かしを入れる必要がある単語文書をロードする      
            Document document = new Document();
            document.LoadFromFile("テスト.docx");
            //新しいテキストウォーターマークオブジェクトを作成し、ウォーターマークとして設定されるテキストを追加する
            TextWatermark txtWatermark = new TextWatermark();
            txtWatermark.Text = "著作権";
            //テキストのフォントサイズ、色、配置を設定する
            txtWatermark.FontSize = 45;
            txtWatermark.Color = Color.Green;
            txtWatermark.Layout = WatermarkLayout.Diagonal;
            //Word文書の透かしとしてテキストを設定する
            document.Watermark = txtWatermark;
            //テキストを保存する
            document.SaveToFile("テキスト透かし.docx", FileFormat.Docx2010);'
```

テキストウォーターマークのレンダリング
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/278784/dba2c579-eb1c-aef8-4fda-bb1d079720a8.jpeg)
SQLのGroupで、文字列を集計

SQLで、集計がよく行うことなんですが、普通は合計値（SUM）、最大最小（MAX,MIN）など、やっていると思います。
文字列のカラムに対して、一行にまとめ出したいケース：
例えばこういうデータがあり：

| userid       |       skill |    
|:-----------------|:------------------|
| 1001             |              R |  
| 1001           |            java |     
| 1001             |              python |   
| 1001             |              shell |   
| 1002           |            work |     
| 1002             |              excel |   

GROUP BY でユーザー単位でスキルを出す

| userid       |       skill |    
|:-----------------|:------------------|
| 1001             | R,java,python,shell |  
| 1002           | work,excel | 

## SQLServerなら、SQLはこうなります：

```sql
SELECT 
userid
,skill = stuff(
  (SELECT  ',' + skill
  FROM table AS t
  WHERE t1.userid = t2.userid FOR xml path('')), 1, 1, '')
FROM table t2
GROUP BY userid
```
## postgresなら、関数があるので、便利です。
```sql

select 
userid
,array_to_string(ag,',')
from (
	select 
	userid
	,array_agg(skill) ag  
	from table 
	group by userid
)a
```
まだ、string_agg()関数もう利用できます。
## ちなみに、REDSHIFTは関数名がちょっと異なります
```sql

select
  userid
 ,listagg(skill,',')
within group (order by skill)
from table
group by 1
```
Vue Test Utils + Jest でVue.jsの単体テストを行う


Vue Test Utilsを使うとVue.jsでテスト行うための便利機能が色々そろっているので、簡単にテストが書けます。

Vue Test UtilsはJest、Karma、Mochaなどのテストランナーと組み合わせて使います。

ここではJestを使っての導入手順を書いていきます。



## 環境



- node: 9.11.2
- yarn: 1.7.0
- vue: 2.5.17
- @vue/test-utils: 1.0.0-beta.24



## パッケージインストール

```bash
$ yarn add -D @vue/test-utils babel-jest jest vue-jest
```



## 設定(Jest)

package.jsonを編集

```json
{
.
.
.
  "scripts": {
    .
    .
    "test": "jest"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!vue-awesome|vuex-i18n)"
    ],
    "transform": {
      ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest"
    },
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/src/$1"
    }
  }
}
```



-  `moduleFileExtensions` : テストするファイル拡張子の指定。
-  `transformIgnorePatterns` : 変換時に無視するファイルを指定。無視したくないモジュールがある場合は上記のように書ける。
-  `transform`  : 変換を行うモジュールの指定。
-  `moduleNameMapper` : パスを省略できる。この場合、例えば `your_project_path/src/example.js` にあるとすれば、 `@/example.js` と書ける。



あとは、

```bash
$ yarn test
```

と打つとテストできます。



## 設定(Babel)

.babelrcを作成、編集します。ESのトランスパイルをテスト時に有効にするための記述です。

これを書かないと自分の環境では `import` が使えないとかでエラーが出ました。

```json
{
  "presets": [
    ["env", { "modules": false }]
  ],
  "env": {
    "test": {
      "presets": [
        ["env", { "targets": { "node": "current" }}]
      ]
    }
  }
}
```

 

## テストを書く

テストは `.spec.js` や `.test.js` といったファイルがあれば自動検知してテストしてくれます。



```javascript
import {mount} from '@vue/test-utils';
import ExampleComponent from '@/ExampleComponent';

describe('ExampleComponent', () => {
  it('is a Vue instance', () => {
    const wrapper = mount(ExampleComponent);
    expect(wrapper.isVueInstance()).toBeTruthy();
  });
});
```



といった感じにテストかけます。

子コンポーネントの影響を受けずにテストしたい場合は、`shallowMount` を使ったりします。



プラグインが必要な場合は、

```js
import {mount, createLocalVue} from '@vue/test-utils';
import ExampleComponent from '@/ExampleComponent';
import ElementUI from 'element-ui';

const localVue = createLocalVue();
localVue.use(ElementUI);

describe('ExampleComponent', () => {
  it('is a Vue instance', () => {
    const wrapper = mount(ExampleComponent, { localVue });
    expect(wrapper.isVueInstance()).toBeTruthy();
  });
});
```





propsを渡して結果をみるテストを書きたい場合は、

例えば、ExampleComponentが以下のようにあったとして、

```vue
<template>
  <div class="title">{{ title }}</div>
</template>

<script>
export default {
  name: 'ExampleComponent',
  props: {
    title: {
      default: '',
      type: String
    }
  }
};
</script>

```



テストは、

```javascript
import {mount, createLocalVue} from '@vue/test-utils';
import ExampleComponent from '@/ExampleComponent';

describe('ExampleComponent', () => {
  it('renders props.title when passed', () => {
    const title = 'てすと';
    const wrapper = mount(ExampleComponent, { 
      propsData: { title }
    });
    const div = wrapper.find('.title');
    expect(div.text()).toBe(title);
  });
});
```

のように書けます。



そのほかにも `trigger` でクリックイベントが呼べたりなど、Vueの単体テストがいい感じに書けて幸せになれます。



## 参考

https://vue-test-utils.vuejs.org/guides/#testing-single-file-components-with-jest
LaravelのPaginationリンクの表示形式を変更する

Laravelの便利な機能にPaginationがあります。
LaravelのPaginationクラスはlinksメソッドでページネーションのリンクを表示するところまでやってくれます。

```php
{{ $paginator->links() }}
```

このとき出力されるHTMLはBootstrap( https://getbootstrap.com/ )準拠らしいですが、バージョンが古いようです。

そこでlinksメソッドにview名の引数を渡すことで、最新のBootstrap4系に対応したHTMLを吐き出してくれます。

```php
{{ $paginator->links('pagination::bootstrap-4') }}
```
CentOS7の自動起動設定

```
$ chkconfig --list
```

うっかり`CentOS7`を使っていたことを忘れていた。

## CentOS7での自動起動設定メモ

```
// 自動起動on
$ systemctl enable サービス名.service

// 自動起動off
$ systemctl disable サービス名.service

// 設定確認
$ systemctl list-unit-files -t service
```


大量に出力されるので、特定の設定を確認したいときはパイプに流す


```
// 設定確認
$ systemctl list-unit-files -t service | grep サービス名

```
PhpStormのメモリを増やしたらキビキビ動作するようになって快適だ

## PhpStormのメモリを可視化するには

「Preference」→「Appearance & Behavior」→「Appearance」→「Show memory indicator」にチェックをいれ「OK」を押す。するとエディタの右下にメモリのインジケーターが表示される。インジケーターにはメモリ使用量とメモリ最大値が表示される。

<img width="1094" alt="Preferences_と_alis2___Volumes_casesensitive_alis2__-_____acca-components_validator_tests_Result_InvalidTest_php__alis2__と_php-playground____Dropbox_projects_php-playground__-_____test_php__php-playground_.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/7f745be5-401d-025e-f9e1-d1381616d6ab.png">

## 手動GCするには

メモリインジケーターをクリックするとGCを走らせることができる。「なんだかもっさりしてきな」と感じたときは押して見ると、もっさり感が解消されることがある。

![2018-08-21 15_55_55.gif](https://qiita-image-store.s3.amazonaws.com/0/889/9466f7f5-c07c-3f95-760e-eae960a4a06c.gif)

## メモリ最大値を増やすには

「Help」→「Edit Custom VM Options・・・」を開き`-Xmx`の値を増やす。

メモリ最大値を2GBにする例:

```
-Xmx2048m
```

保存したら、PhpStormを再起動する。
Exchange Onlineで先進認証に対応したメールクライアント一覧

# 概要
Azure ADの条件付きアクセスにレガシー認証を利用させないオプションが付きました。
これによりExchange OnlineでPOP/IMAPはもちろん、Active Syncの接続も簡単に止めることができます。

利用できるアプリケーションが限定されてガバナンスが効きやすくなったのはいいのですが、そもそもユーザーにどのアプリを利用させるのがいいか悩むところです。
そこで今回Azure ADの条件付きアクセスでレガシー認証をブロックした状態で利用できるアプリケーションを探してみることにしました。

# Azure ADの設定
Azure AD の条件付きアクセスで「モバイルアプリとデスクトップクライアント」の接続を先進認証のみとします。以下の画面のようにモバイルアプリの先進認証以外をすべてブロックしています。
![キャプチャ255.JPG](https://qiita-image-store.s3.amazonaws.com/0/262585/bc88b3df-6e6b-2d7e-b97f-a0c21cd54de1.jpeg)

これで対象ユーザーは先進認証しか使えなくなります。この状態でアクセスできるクライアントを検証しました。



# 先進認証で利用できるアプリ一覧
## Windows 10
Outlook 2013 以降（先進認証を有効）
Windows Mail（Windows 10)

## iOS
標準のメール
Outlook for iOS

## Android
Outlook for Android
ナイン

## macOS
標準のメール（Mojaveで確認）
Outlook for Machintosh




#まとめ
今回は先進認証で利用できるメールクライアントを調べてみました。
これでメール環境をより安全に運用することができるようになります。

Windows10やiOSについては標準で利用できるメールクライアントが実装されているので困ることがないようですが、AndroidではほとんどのメールクライアントがActiveSync までしか対応しておらず、結果的にOutlookを利用することになりそうです。
企業では強制が効きやすいと思いますが、学校などガバナンスが聞かないところではユーザーの利用シナリオを作成するのが難しいです。

ほかにもあるよといった情報があればコメントいただけますと幸いです。


# 最終更新
2018/9/4 継続調査中
2018/12/16 Macの標準メールの動作をMojaveで確認。最初はMac mini 2014でやってたのでうまく動かなかったのですが、どこかのアップデートで対応したようです。
標準ライブラリのvecモジュール和訳してみた

Rustに普及してほしいので標準ライブラリを訳そうと思い、その第一歩としてvecモジュールを訳してみました。
想像以上に大変だったのでもう挫けました。また元気が出たら次はsliceを訳してみます。

# 成果物

https://moshg.github.io/rust-std-ja/std/vec/

# 翻訳手順

必要なもの: Python

**現在この手順ではドキュメントをビルドできません。**
詳しくは[rust/README.md](https://github.com/rust-lang/rust/blob/master/README.md)を参照してください。

* https://github.com/rust-lang/rust をクローン。
* rustdocを翻訳。
  * stdを訳したいならソースはsrc/libstdにあります。
  * stdは他のクレートの単なるre-exportを含むので注意してください。OSに依存しない機能はcore、ヒープに関連する機能はallocで実装されています。
* リポジトリのトップでコマンド "python x.py doc src/libstd" を実行 (すごく長い)。

# 最後に

アドバイスがありましたら気軽にお知らせください。
railsで多対多のモデルを作る

いつもやり方を忘れて過去のコードを振り返ったりするので備忘録としてまとめました。

# やること
<img width="862" alt="スクリーンショット 2018-08-21 13.55.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/235554/fbfeabd8-12bf-520d-4a7f-7b0bab2b5996.png">
これのうちの、clips, clip-categories, boardsの多対多の関係を作る
(clip modelすでに実装済)

# 実装

```
$ rails g model board user:references name:string
# user:referencesはuserに紐づけるために必要なだけなので、本筋とは関係ない
$ rails g model clip_category clip:references board:references
```

```20180821062745_create_clip_categories.rb
class CreateClipCategories < ActiveRecord::Migration[5.2]
  def change
    create_table :clip_categories do |t|
      t.references :clip, foreign_key: true
      t.references :board, foreign_key: true

      t.timestamps
    end
    add_index :clip_categories, [:clip_id, :board_id], unique: true #　追加
  end
end
```

```
$ rails db:migrate
```

board.rbに以下を追加

```board.rb
has_many :clip_categories, foreign_key: :board_id, dependent: :destroy
has_many :clips, through: :clip_categories
```

clip.rbに以下を追加

```clip.rb
has_many :clip_categories, foreign_key: :clip_id, dependent: :destroy
has_many :boards, through: :clip_categories
```

以上で紐づけが完了です。

```.rb
clip.boards
```

などが使えます。
django migrate時のduplicate key name

# TL;DR
SQLが得意な人は読んでも当たり前のことが書いてあります。
djangoでmigrationファイルを作成して、migrateする時にエラーに遭遇したので解決策を探しました。

免責的ですが、djangoによる根本的な解決策にはなっていません。
（私の調査では、問題に対する対症療法しか見つけられてないです。）

本質的には、このエラーが起こらないために、
どうしたほうがいいのかを考えるべきなのですが、まだ考えがまとまっていません。
たとえば、インデックスを付与するタイミングであるとかフローとか不明な点が多いです。

今回のエントリーについては、エラーに対してSQLで強引に解決したのでバッドプラクティスだと思います。


# 問題設定
 
```common-lisp
> python manage.py migrate
....
....
django.db.utils.OperationalError: (1061, "Duplicate key name 'xxxx'")
```

これだけで伝わる人はそれほど多くないかもしれません。
簡単に意訳すると、

> djangoでDBを操作しようとしたけど、xxxっていう重複したキーのせいでエラー起きてるよ

って言ってます。
djangoに限らず、調べた限りではrailsでも同じような問題を探索してる人がいました。
コミュニティの大きさと多様性の重要性が身にしみてわかります。詳しくは、[リファレンス](# Reference)で

# 解き方
StackOverFlowやProgressのエントリーによると、

> * I just ran in to this error and I was able to solve it by dropping the index named in the error. (Stack Over Flow)

> * Recreate the index by first dropping the index and creating it back again (Progress)

要は、
「インデックス落としてもう一回作れ」
ってことみたい。つまり、SQLに翻訳するなら

```sql:
> DROP INDEX key_name ON table_name 
```

をしろとのこと。

他にも、--fake使ってやる人もStackOverFlowにはいたみたいだけど、
この人自身があんまりいいやり方じゃないって言ってますね。
複数ソースを見た感じ、これが共通の今の僕に探せるベターな解決策でした。

# おまけ
--fakeってなんだっけ？　
答） manage.py migrateの引数です。

そういうことではないよね笑
[django公式](https://docs.djangoproject.com/ja/2.1/ref/django-admin/#migrate)によると

> --fake
Marks the migrations up to the target one (following the rules above) as applied, but without actually running the SQL to change your database schema.

>This is intended for advanced users to manipulate the current migration state directly if they're manually applying changes; be warned that using --fake runs the risk of putting the migration state table into a state where manual recovery will be needed to make migrations run correctly.

意訳するなら

> このコマンドを使うと、変更したいターゲットのテーブルなどに対して、マイグレーションが適用されたことにする。しかし、実際にはデータベースを変更するクエリは実行されない。
> この操作は、SQL操作に長けたユーザーが使うことを想定している。例えば、彼らが手動でDBを変更している場合に、現在のマイグレーションを直接操作するケースとか。
ただ、--fakeを使うことのリスクにはリスクがある。具体的には、正しくマイグレーションするために、今までのマイグレーションの状態を手動で元に戻さなくてはならない状態に陥る可能性である。

って感じだろうか。どちらにしても僕は、advanced userではないから厄介になることはなさそうです。


# Reference 
## 本編
1. https://stackoverflow.com/questions/34598177/django-database-migration-error-duplicate-key
2. https://knowledgebase.progress.com/articles/Article/000048785
3. http://d.hatena.ne.jp/japanrock_pg/20110225/1298623790
4. https://dev.mysql.com/doc/refman/8.0/en/drop-index.html


## おまけ
5. https://www.ganbaruyo.net/details/django-migration-error/
6. http://nissy0409.hatenablog.com/entry/2015/09/22/061147
7. https://docs.djangoproject.com/ja/2.1/ref/django-admin/#migrate
Google Cloud Functionsで環境変数を設定する

https://cloud.google.com/functions/docs/env-var
上記リンクに書いてある通りなんですが、`--set-env-vars`か`--env-vars-file`のフラグを付けてdeployをする
~~ポイントはbetaを使うところ~~ Cloud SDK 227.0.0 (2018-12-04)よりbetaが必要なくなった

```
$ gcloud functions deploy functionname --set-env-vars="env1"="value","env2"="value2" --source='https://source.developers.google.com/projects/hogehoge/repos/foo/moveable-aliases/branchname' --runtime=nodejs8 --trigger-http 
```
更新するときは`--update-env-vars`を使う。環境変数のみで良い

```
$ gcloud functions deploy functionname --update-env-vars="env1"="valu2","env2"="value3","env3"="value4"
```

確認にはdescribe

```
$ gcloud functions describe functionname | yq '.environmentVariables'
{
  "env": "value",
  "env2": "value2",
  "env3": "valu3"
}


```
【jQuery】追従ヘッダーの構造を理解しよう！

#スクロールしたら付いてくるヘッダー
最近は比較的見なくなったような気もしますが、私は職場で割と使います。
で、追従ヘッダー！？なんか難しそうじゃね！？と思っていた私は先人たちの素晴らしいアイテムをDLしては切り貼りし・・・
を繰り返していたのですが、地味に大変。（CSSいじったり・・・とか）
というわけで、自分で一から考えて設置できるか実験してみました！

##結果から
<p data-height="265" data-theme-id="0" data-slug-hash="bxGjvM" data-default-tab="html,result" data-user="kapeking" data-pen-title="追従ヘッダー" class="codepen">See the Pen <a href="https://codepen.io/kapeking/pen/bxGjvM/">追従ヘッダー</a> by かぺ (<a href="https://codepen.io/kapeking">@kapeking</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
結構それっぽくない？（自画自賛）

###自分的に取り入れたかったこと

+ ヘッダーが何層かあるときに必要な層のヘッダーだけ追従させたい
+ 追従してるときは半透明にしたい
+ 追従に切り替わるときに「かくん」ってならないようにしたい

ではざっくり解説していきます！

##解説① 考え方
###動く前と動いた後の違い
【動く前】
![ビフォー.jpg](https://qiita-image-store.s3.amazonaws.com/0/276676/5a3f62a2-5568-0fa2-51c7-9c3d6d5441e8.jpeg)

【動いた後】
![アフター.jpg](https://qiita-image-store.s3.amazonaws.com/0/276676/7639f35b-3451-dbe5-34b5-605005280944.jpeg)

画像より。
nav01 前：普通 後：表示なし⇒display:none;でいけそう
nav02 前：普通 後：半透明で上部固定⇒background:rgba(252, 74, 26,0.8);で半透明、position:fixed;でウィンドウ固定
nav03 前：普通 後：表示なし⇒display:none;でいけそう

⇒つまり全部CSSでいけそう

###トリガー
何きっかけで変化が起こるのか？⇒スクロールしたら⇒nav02のとこまでスクロールしたら
なんとなくCSSでは無理そうだからここはjQueryで。

###まとめると
jQueryでスクロールイベントを作り、発火したら用意したクラス名をつけたり外したりしたらいける気がする。

##解説② やってみよう！【jQuery編】
早速だけど、jQueryのスクロールイベントってどういうやつなのかしら（全く分からない）
ネットで探してみたらちょうどいいやつ見つけました。

参考資料 [スクロールしたらヘッダーの一部だけ固定する](http://chibinowa.net/note/js/fixedheader.html)

```js:スクロールイベントの例

$(window).on('scroll', function() {
  $('ヘッダーのクラス名を追加したい要素').toggleClass('追加するクラス名', $(this).scrollTop() > 〇〇px以上スクロールしたら発火するよ！)
});
```
こんな感じでいけそう。on(scroll)とか.scrollTop()とかはよくわからないので調べます ⇒<font color="blue">【宿題】スクロールイベントについて調べる（後日提出）</font>

##解説③ やってみよう！【CSS編】
今回追加したり外したりするクラス名を **fixed** とします。（参考資料のまま）
先にイベント発生前（要するに普通）のヘッダーとかナビとかを作ります

```html:html
<nav>
  <div class="nav01">
    <h1>かぺの王国</h1>
  </div>
   <div class="nav02">
    <p>WORK</p>
     <ul>
       <li>home</li>
       <li>plofile</li>
       <li>work</li>
       <li>contact</li>
     </ul>
  </div>
 <div class="nav03">home > work > page01</div>
</nav>
<p class="main">親譲りの無鉄砲で小供の時から損ばかりしている。・・・（青空文庫より）
</p>
```

```css:css
body{
  color:#FFF;
  margin:0;
}
body p{
  margin:0;
}
.nav01{
  background:#4abdac;
}
.nav02{
  background:#fc4a1a;
  display:flex;
  justify-content:space-between;
  align-items:center;
}
.nav02 ul{
  list-style:none;
  display:flex;
}
.nav02 p{
  font-size:20px;
  font-weight:bold;
}
.nav02 ul li{
  margin-left:20px;
}
.nav03{
  background:#f78733;
}
.nav01,.nav02,.nav03{
  padding:5px 20px;
  box-sizing:border-box;
}
.main{
  color:#444;
  line-height:4;
  background:#dfdce3;
}
```
ここにイベント発生後に起きてほしい変化を.fixed付きでcssに追加します。

```css:追加するCSS
.nav01.fixed,nav03.fixed{
  display:0;
}
.nav02.fixed{
  width:100%;
  background:rgba(252, 74, 26,0.8);
  position:fixed;
  top:0;
  left:0;
  z-index:99999;
}
```
・・・動かしてみてわかりましたが、nav01とnav03のdisplay:0;はあってもなくても一緒ですね（笑）
せっかくだから残しとこ。

というわけで自作追従ヘッダー第一号完成です！もっといい方法ありそうだから改良していく予定です。
ログファイルをリアルタイムで表示させるtailコマンド

#やりたいこと
タイトルの通り

#解決策
```
$ tail -f ファイルパス
```

`-f`： リアルタイムで中身を表示するオプション

#エラーログだけをリアルタイムで表示したい時
```
$ tail -f ファイルパス | grep ERROR
```
上記はfuelPHPで実装している場合ですので、各フレームワークでgrepする内容は選んでください
【Androidアプリ開発勉強】開発時にハマったこと(XAMLでデザイン編)

実際に開発を始めてハマったことの備忘録です。
今回はXAMLでDesignタブに、
レイアウトやらウィジェットやらを置いている時にハマった問題の備忘録です。

# 前提環境(バージョンとか)

Android Studio Version 3.1.4
Windows 10 HOME Version 1803, OS build 17134.228


# ハマったこと

## Designタブのpreviewにテキストボックスなどが表示されない
build.gradle(app)内のAndroid Appcompatというライブラリのバージョンが新しいと発生するバグらしい。
以下のサイトを参考に解決。多謝。

[[エラー対策]レイアウトファイルでビューが表示されない・貼り付けできない場合の対処法](https://minpro.net/layout-editor-view-not-showup)

ちなみに上記サイトだとalph1なら治ると書いてあるが、
メモ時点(2018年8月20日現在)では治らなかった。
自分は安定版である27.1.1にしたら治った。
(ちなみにいまはrc1が最新になっているそうです)

## RelativeLayoutがない問題
ネットで調べるとRelativeLayoutを使う例が多いんだけど、
IDEにRelativeLayoutが無い。
いろいろ調べてみるとRegacyタブにあった…。

気にしなければそのまま使えば良いんだろうけど、
せっかくなのでConstraintLayoutを使って開発することに。

## 画面右下に固定ボタンをおきたい
FloatingActionButtonを使う。
これをRelativeLayoutで実現したかったんだけどもっと簡単に出来た。

ちなみに画面上部に固定のボタンを置きたかったんだけど、
これはそのままボタンを置いて、
その下にScrollView置くことで実現した。

## XMLで使用する色の指定
res/values/colors.xml内に定義すると使用できる。
こんな感じで書いとくと、
`<color name="default_color">#FF4081</color>`

この様に指定出来る。
`android:textColor="@color/default_color"`

## Missing Constrains in ConstraintLayoutというメッセージ
このメッセージはConstraintLayoutを使用している時に、
Widget(ボタンとか)の配置を決定していないと出るメッセージみたい。

Designタブで位置をちゃんと指定してあげたら消えた。


## MPAndroidChart使えない問題。
使い方をぐぐったらbuild.gradleに書けばOKということだったのだが、
そのとおりに書いたらエラーになった。

【エラー内容】
Could not find method compile() for arguments [com.github.PhilJay:MPAndroidChart:v2.1.5] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

公式の英語ドキュメントを見たら解決した。

つい日本語ドキュメントを求めちゃうけど、
ちゃんと公式の英語ドキュメントを見たまえって話ですね。
手順としては以下の通り。

+ Projectのbuild.gradleのdependenciesに以下を記載。
`implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'`

+ appのbuild.gradleのallprojects > repositories に以下を記載。
`maven { url "https://jitpack.io" }`

# レイアウトしてみて
慣れてないというのがあるけど、
思ったより時間がかかったなぁという印象。

やっぱりネットの情報でも古くなっている場合が多くてハマる。
後半は順調に作業出来たので、
これに限らないけど導入の敷居を下げられるともっと楽できるのになーと思う。
token interceptor 

package com.smartt.api.interceptor;  
  
import java.lang.annotation.*;  
  
@Target(ElementType.METHOD)  
@Retention (RetentionPolicy.RUNTIME)  
@Documented  
public @interface Token {  
   boolean save() default false;  
   boolean remove() default false;  
}  

package com.smartt.api.interceptor;  
  
import java.lang.reflect.Method;  
import java.util.UUID;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
import org.springframework.web.method.HandlerMethod;  
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
  
public class TokenInterceptor extends HandlerInterceptorAdapter {  
      
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        if (handler instanceof HandlerMethod) {  
            HandlerMethod handlerMethod = (HandlerMethod) handler;  
            Method method = handlerMethod.getMethod();  
            Token annotation = method.getAnnotation(Token.class);  
            if (annotation != null) {  
                boolean needSaveSession = annotation.save();  
                if (needSaveSession) {  
                    request.getSession(false).setAttribute("token", UUID.randomUUID().toString());  
                }  
                boolean needRemoveSession = annotation.remove();  
                if (needRemoveSession) {  
                    if (isRepeatSubmit(request)) {  
                        return false;  
                    }  
                    request.getSession(false).removeAttribute("token");  
                }  
            }  
            return true;  
        } else {  
            return super.preHandle(request, response, handler);  
        }  
    }  
  
    private boolean isRepeatSubmit(HttpServletRequest request) {  
        String serverToken = (String) request.getSession(false).getAttribute("token");  
        if (serverToken == null) {  
            return true;  
        }  
        String clinetToken = request.getParameter("token");  
        if (clinetToken == null) {  
            return true;  
        }  
        if (!serverToken.equals(clinetToken)) {  
            return true;  
        }  
        return false;  
    }  
}
Delphi Community Edition Meet up ! - FireDAC VCL 編

これは、2018年8月3日に行なった Delphi Community Edition Meet up ! で行なった[データエクスプローラのデモ](https://qiita.com/CYonezawa/items/3e58e7f6db9ff5bc7434)で、FireDAC 接続を使って、サラッとデータを表示する VCL アプリケーションを作った際の説明です

データエクスプローラは、アプリケーションの作成の時にも効力を発揮します
予め接続する先のデータベースが決まっているのであれば、データエクスプロラー上に接続情報を作成しておくことで、必要なプロパティが設定されたコンポーネントを生成してくれます

## デモで行なったこと
VCL アプリケーションを新規に作成して、ノンコーディングでデータを表示するアプリケーションを作り実行しました

## デモの手順

### 1. VCL の新規アプリケーションを作成します
Delphi のメニューから「ファイル｜新規作成｜VCLフォームアプリケーション - Delphi」を選択します
後の手順のこともあるので、フォームの大きさを広げておきます
![firedac01_1.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/d605b634-e091-020b-b58e-4f6894a79226.gif)


### 2. データエクスプローラから接続設定をフォーム上にドラックアンドドロップして、接続に必要なコンポーネントを生成します
データエクスプローラ側の設定等については [Delphi Community Edition Meet up ! - データエクスプローラ編](https://qiita.com/CYonezawa/items/3e58e7f6db9ff5bc7434) を参照してくださいませ
このデモでは、データエクスプローラ上の Local DB (dbdemos.gdb) 内の BIOLIFE テーブルを使用しています

データエクスプローラ上で Local DB に接続して、BIOLIFE テーブルをドラックしてフォーム上にドロップします
この動作によって、フォーム上に予め接続設定が行なわれている Local Connection (TFDConnection) と、Biolife Table (TFDQuery) が自動生成されます

![firedac01_2.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/76ee84bb-7d1e-71ec-f22e-36a68b2e5f5a.gif)

### 3. フィールドエディタに、テーブルのフィールドを追加します
Biolife Table コンポーネントをマウスで選択して、マウスの右ボタンをクリックします
ポップアップメニューから「フィールドエディタ」を選択します
表示されたフィールドエディタ上でマウスの右ボタンをクリックします
ポップアップメニューから「すべてのフィールドを追加」を選択します

オブジェクトインスペクタ上で、Biolife Table (TFDQuery) の Active プロパティが True になっていない場合は True にして、データベースのテーブルと接続しておきます

設計時でも接続できるってスゴイ！
![firedac01_3.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/2e272201-864d-2328-c957-0ad7d08c4605.gif)

### 4. 追加したフィールドをフォーム上にドラックアンドドロップして、データを表示するコンポーネントを生成します

フィールドエディタ上のフィールドをすべて選択して、フォーム上にドラックアンドドロップ！

VCL の場合は、データセット上のデータを扱うためのコンポーネントが予め決まっています
たとえば、文字データであれば TDBEdit、画像データなら TDBImage というようにです
なので、フィールドエディタからドラッグアンドドロップで、フィールドをフォーム上に配置すると、予め決まられたコンポーネントが生成されて、フォーム上に展開されます
![firedac01_4_1.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/d868f8b4-52eb-df39-5a90-cbe0383ec943.gif)

実データが設計時に表示されれるので、コンポーネントの大きさの調整とかとても便利

### 5. ナビゲータを追加して、設定する
カレントのデータだけ見せるだけだと、面白くないので、データを前後に送るためのナビゲータを追加します
ツールパレットから、TDBNavigator をフォームにドラックアンドドロップします
オブジェクトインスペクタ上で、DBNavigator1 の DataSource プロパティを DataSource1 に設定します
![firedac01_5.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/5812acc5-5433-3585-864b-f9f78b5313c7.gif)

### 6. 実行する
ナビゲータのボタンを操作すると、カレントのカーソルが前後し、対応するデータが表示されます
![firedac01_6.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/bba97676-78e8-3653-7ba3-7d2da5852f9f.gif)

## あとがき
今回は簡単なデモでしたので、フォームにそのままペタペタ貼りましたが、データモジュールを使って、ロジックと UI を分けた方がベターです（拡張や修正の面からも）