at backyard

Color my life with the chaos of trouble.

Warning: unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React. という警告を直した際のメモ

react-railsでアプリを書いていると、下記のような"warning"に出会った。

Warning: unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React.

調べてみると下記のissueにたどり着いた。

github.com

内容を見てみると、以前に修正されてはいるんだけど、バージョン上げたらまた出てきたよ!という内容のようだ。
なお、この時点での最新バージョンは下記のとおりとなる。
・react-rails (v2.2.0)
・webpacker gem (v2.0)

---------追記---------

そうそう、自身の環境を書き忘れていたので、下記に追記
Rails 5.0.2
・react-rails (1.11.0)

なお、webpackerは使用していない。

------追記終わり------

そして、以前あがっていたissueとは下記のものになるよう。

github.com

issue内にも書かれているとおり、下記のコードを"application.js"に追記したら、warningが出なくなった。

ReactRailsUJS.handleEvent('turbolinks:before-cache', function() {
  window.ReactRailsUJS.unmountComponents();
});


ちなみにreact-railsは今年リリースした"Sauna Map of Japan"にて使用中。
フロント側は元々jQueryで書いていたのだが、今回react-railsを使って、絶賛書き直し中。
自身の勉強を兼ねてもいる。今更な話ではあるが、react良いですね〜

react-rails

github.com


ちなみにSauna Map of Japanはまだベータ版。少しずつではあるが、使いやすいものにしていきます。

Sauna Map of Japan

https://sauna-map-of-japan.herokuapp.com/


そういえば、久しぶりのブログ更新になりました。
あと、少し前にMediumにも近況載せました。
最近フロントエンド側でコード書いていますよ、という話。

medium.com

Sauna Map of Japan - β

先日Sauna Map of JapanをBetaにあげました。
どんな機能追加が行われたかについては当サイトのChange logを引用します。

Betaリリースに伴い、下記の機能が追加されています。
・日本地図からの検索が県単位で行えるようになりました
・ユーザがサウナ情報の登録を行えるようになりました(ログイン時のみ)
・ユーザのコメント履歴をユーザページに追加
・ユーザアカウント作成時のメールアドレス認証

Railsで作られているSauna Map of Japanでは認証周りに"sorcery"を使用しているのですが、
とても使いやすくて重宝しています。
今回実装したメールアドレス認証もsorceryのおかげ。

Sauna Map of Japan - α

5/3に"Sauna Map of Japan"というサウナの情報サイトをリリースしました。
まだα版(試作段階)なので、今後色々と更新・変更を加えていく予定です。が、ひとまず先に公開してしまいます。 (最近サウナにハマっている自分自身が、実際に使いながら改良を加えていきたいということもあり)

https://sauna-map-of-japan.herokuapp.com/

改善点やバグなど見つかりましたら、ご連絡いただけると幸いです。

4月。春の雨。最近のことをちょろっと書く。

最近、ブログを更新する習慣がパタリとなくなってしまった。
プライベートで黙々とRailsアプリを書いているからかもしれない。
GWまでにはベータ版を公開したい。そして旅行とか行く際に、自分自身が存分に活用したい。
出先でいろいろなサウナに入ってみたいので。というわけで、サウナがキーワードのWebアプリ書いています。

ElixirConf 2017

http://www.elixirconf.jp/www.elixirconf.jp

行ってきた。
下記は感想・メモなどをまとめてくれたりしている方々の記事、あとtogetter。
あとで読もうとしているので、自分へのメモとして貼っています。

http://in.fablic.co.jp/entry/elixir-conf-japan-2017in.fablic.co.jp

thinca.hatenablog.com

togetter.com

Elixirは最近触り始めたばかりだし、あまり周辺の知識もないのだが、色々と話が聞けて面白かった。
今回聞けた話を伝ってElixir周りやErlang周辺を色々と調べてみたい。
時間ができたら、自身でも取っていたメモをちゃんと整理して、ブログに書きたい <= 自分の頭の整理も兼ねて。

Phoenixでも簡単なアプリを書いてみたが、書いてみた第一印象は思っていた以上にRailsっぽい。
勿論、全然違う側面もあるのだけど、入り口というか、精神的な敷居としてはかなり低く、
想像していたよりは抵抗なく入っていける感じがとても印象良かった。

PAUL McCARTNEY THE LIFE

※下記はAmazonへのリンクとなっています。

最近知ったんだけど、"ポールが初めて認めたバイオグラフィー"という売り文句で、本が発売されたらしい。
気づいてすぐにKindleで購入して今読んでいるところ。
まだ読み始めたばかりだが、とても面白い。
ま、ポール好きなので、当然面白い。

春の雨

春の雨ってやつですね、この土日は。 春の雨といえば、大昔に作ったこの曲を思い出す。 Peruriと言います。

youtu.be

様々な言語からMinioのファイルアップロードを試す

様々な言語からMinioを試してみる。
※といっても、現在は3言語しかまだ書いていない

f:id:shinshin86:20170318082954p:plain

最近 Go言語で書かれた、S3互換のオブジェクトストレージサーバを触り始めたので、
各言語での試し方をこちらにメモしておく。
なお、あくまで現時点でのやり方となるので、もしこの記事が古くなっているようだったら、
公式からDocsに飛んで確認するのが望ましい。

www.minio.io



まずはNode.jsから

Node.js

セットアップ

npm install minio

実装

const Minio = require('minio');
const fs = require('fs');
const path = require('path');

const location = 'us-east-1';

const minioClient = new Minio.Client({
  endPoint: END_POINT,
  port: PORT,
  secure: false, // テストなのでひとまずfalseにしている
  accessKey: ACCESS_KEY,
  secretKey: SECRET_KEY
});

// Bucket作成
function createBucket(bucketName) {
  minioClient.makeBucket(bucketName, location, function(err) {
    if(err) return console.log(err);

    console.log('Bucket created successfully in ', location);
    console.log('Created bucket name  => ', bucketName);
  });
}

// imagesディレクトリ内の画像ファイルを作成したBucketに全てアップロードする
function fileUpload(bucketName, uploadDir) {
  let files = fs.readdirSync(uploadDir);
  files.forEach(function(file) {
    console.log('Upload file =>', file);

    // アップロードするファイル名
    let filePath = path.join(uploadDir, file);
    // fPutObjectを使用してファイルをBucket "SampleImages"にアップロードします
    minioClient.fPutObject(bucketName, file, filePath, 'image/png', function(err, etag) {
      if(err) return console.log(err);
      console.log('File upload successfully!!');
      console.log('Uploaded File Name => ', file);
    });
  });
}

// 作成するBucket名
const bucketName = 'nodetest';

// アップロード対象が格納されたディレクトリ名
let targetDir = 'images';

// アップロード対象の絶対パス
let uploadDir = path.join(__dirname, targetDir);

// 実行
createBucket(bucketName);
fileUpload(bucketName, uploadDir);

Python

セットアップ

pip install minio

実装

from minio import Minio
from minio.error import ResponseError
import os
import glob

# テストなのでひとまずsecureはFalseにしている
minioClient = Minio(END_POINT,
    access_key=ACCESS_KEY,
    secret_key=SECRET_KEY,
    secure=False)

# Bucketを作成する
def create_bucket(bucket_name):
    try:
        minioClient.make_bucket(bucket_name, location='us-east-1')
    except ResponseError as err:
        print(err)

# 対象ディレクトリなのファイルを取得し、アップロードする
def file_upload(bucket_name, upload_dir):
    for i in glob.glob(os.path.join(upload_dir, '*.png')):
        try:
            minioClient.fput_object(bucket_name, os.path.basename(i), i)
        except ResponseError as err:
            print(err)


# 作成するBucket名
bucket_name = 'pythontest'

# アップロード対象のファイルが格納されたディレクトリ名
target_dir = 'images'

# アップロード対象の絶対パス
upload_dir = os.path.join(os.getcwd(), target_dir)

print('File upload start');
create_bucket(bucket_name)
file_upload(bucket_name, upload_dir)
print('File upload successfully!')

Go

セットアップ

go get -u github.com/minio/minio-go

実装

package main

import (
	"fmt"
	"github.com/minio/minio-go" // Import Minio library.
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
)

func main() {
	bname := "gotest"
	tdir := "images"
	tpath, err := os.Getwd()
	ssl := false // テストなのでひとまずfalseとしている
        location := "us-east-1"

	minioClient, err := minio.New(Endpoint,
		AccessKey,
		SecretKey, ssl)

	if err != nil {
		log.Fatalln(err)
	}

	// bucketを作成
	err = minioClient.MakeBucket(bname, location)
	if err != nil {
		// 既に同名のbucketが存在していないかを確認する
		exists, err := minioClient.BucketExists(bname)
		if err == nil && exists {
			fmt.Printf("We already own %s\n", bname)
		} else {
			log.Fatalln(err)
		}
	} else {
		fmt.Printf("Successfully created %s\n", bname)
	}

	// 指定したディレクトリからファイルを取得
	filelist, err := ioutil.ReadDir(filepath.Join(tpath, tdir))

	if err != nil {
		fmt.Println(err)
		return
	}

    // 取得したファイルをすべてアップロードする
	for index, element := range filelist {
		fmt.Printf("Uploading... %s : %d\n", element.Name(), index)

		n, err := minioClient.FPutObject(bname, element.Name(), filepath.Join(tpath, tdir, element.Name()), "image/png")
		if err != nil {
			log.Fatalln(err)
		}
		fmt.Printf("Successfully uploadefd %s of size %d\n", element.Name(), n)
	}
}

ひとまずここまで。
汚いコードをただ書き散らしているような気もする。。。精進していかねば。

あと、昨日からElixir触り始めたので、Elixirのサンプルも近々書きたい。


ちょっと試すだけでも使用コストがかかってしまうAmazon S3の代替手段として
Minioの存在価値はとてもあると思う。気軽にローカルでの開発などに使えるので、とても便利。

インストール関連の記事は検索してみると色々出て来るし、公式のスタートガイドも分かりやすい。

いいですね、Minio

Ruby on Rails 5でページ遷移時にJavaScriptが読み込まれない問題の解決法

個人度がいつも以上に高い備忘録なので、この内容がリーチしない方にとっては読む意味ありません。

表題の件で悩まれている方がこのページに訪れた際は、下に貼ったリンク先の記事が解決の手立てとなるかもしれませんので、ぜひ見てみてください。
(現に私が解決したので)


Rails 5でアプリ書いているとき、ページ遷移時にJavascriptが読み込まれなくて困っていた。
解決のきっかけになったのは、下記の記事

qiita.com


最初、下記のように書いていたのだけど、これが間違えていた。

$(document).on 'ready page:load', ->
  console.log("call function!")

上に貼った記事にもある通り、この書き方ではRails 5に対応していないようだ。
正しくは下記。

$(document).on 'turbolinks:load', ->
  console.log("call function!")

感謝!