tofucodes diary

にほんごのほう

Rails 5でAPIをさくっと作る方法

Rails 5のAPI専用モードでAPIのベースをさくっと作ってみたので備忘録として。

Rails開発環境の構築

Railsの最新バージョン(5.1.4)

$ gem install rails
...
12 gems installed

APIアプリケーション作成

$ rails new scribbles_api --api
...
RubyDep: WARNING: Your Ruby is outdated/buggy.
RubyDep: WARNING: Your Ruby is: 2.3.0 (buggy). Recommendation: upgrade to 2.3.1.

rubyのバージョンアップ

$ rbenv install 2.3.1
Downloading ruby-2.3.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.bz2
Installing ruby-2.3.1...

BUILD FAILED (OS X 10.12.6 using ruby-build 20160602)

Inspect or clean up the working tree at /var/folders/tz/_ldn35g52dl43l019mrzqfq00000gn/T/ruby-build.20171014151748.9497
Results logged to /var/folders/tz/_ldn35g52dl43l019mrzqfq00000gn/T/ruby-build.20171014151748.9497.log

Last 10 log lines:
  Referenced from: /private/var/folders/tz/_ldn35g52dl43l019mrzqfq00000gn/T/ruby-build.20171014151748.9497/ruby-2.3.1/./miniruby
  Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: _utimensat
  Referenced from: /private/var/folders/tz/_ldn35g52dl43l019mrzqfq00000gn/T/ruby-build.20171014151748.9497/ruby-2.3.1/./minir
uby
  Expected in: /usr/lib/libSystem.B.dylib

make: *** [.rbconfig.time] Abort trap: 6
make: *** Waiting for unfinished jobs....
encdb.h updated

https://github.com/rvm/rvm/issues/3744
再度インストール

$ xcode-select --install

$ rbenv install 2.3.1
...
Installed ruby-2.3.1

$ rbenv local 2.3.1
$ rbenv rehash

$ gem install bundler
...
1 gem installed

$ bundle install
...
Bundle complete! 8 Gemfile dependencies, 49 gems now installed.

API作成

scaffoldでモデル・コントローラ作成

$ rails g scaffold User field1:type field2:type

ダミーデータ作成
以下の記事を参考にさせていただきました

Gemfile

# seeds
gem 'enumerize'
gem 'activerecord-import'
group :development, :test do
    gem 'faker'
    gem 'gimei'
end

lib/tasks/seed.rake

Pathname.glob(Rails.root.join('db/seeds/*.rb')) do |path|
    desc "Load the seed data from db/seeds/#{path.basename}."
    task "db:seed:#{path.basename(".*")}" => :environment do
        load(path)
    end
end

db/seeds/user.rb

# coding: utf-8

# Create dummy users
# Male
users = []
50.times do |no|
  gimei = Gimei.male
  users << User.new(
    user_hash: SecureRandom.uuid,
    nickname: gimei.katakana,
    email: Faker::Internet.email,
    password: Faker::Lorem.characters(45),
    gender: User.gender.male.value,
  )
end

# Female
50.times do |no|
  gimei = Gimei.female
  users << User.new(
    user_hash: SecureRandom.uuid,
    nickname: gimei.katakana,
    email: Faker::Internet.email,
    password: Faker::Lorem.characters(45),
    gender: User.gender.female.value,
  )
end

# Bulk insert
User.import users

ここまでやるとrakeのseedタスクがこんな感じ

rake -T db:seed
rake db:seed           # Loads the seed data from db/seeds.rb
rake db:seed:user      # Load the seed data from db/seeds/user.rb

あとは実際に実行してUserのダミーデータを作成

$ rake db:migrate
$ rake db:seed:user

rails routes確認

$ rails routes
Prefix Verb   URI Pattern              Controller#Action
 users GET    /users(.:format)         users#index
       POST   /users(.:format)         users#create
 user  GET    /users/:id(.:format)     users#show
       PATCH  /users/:id(.:format)     users#update
       PUT    /users/:id(.:format)     users#update
       DELETE /users/:id(.:format)     users#destroy

ローカルサーバ起動

$ rails server
=> Booting Puma
=> Rails 5.1.4 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.10.0 (ruby 2.3.1-p112), codename: Russell's Teapot
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000

curlで動作確認OK

$ curl "http://localhost:3000/users/1"
{"id":1,"user_hash":"3c929a28-3583-45a8-a71d-82295a2a6a3a","nickname":"タムラ コウタロウ","email":"vada@borerherman.com","password":"0pm8iatqkbk3n7x7vnxofwskk0aws5oyfvvj62r5y7nop","gender":"male","created_at":null,"updated_at":null}

iOS 11からNSLocaleの仕様が変更されたらしい

使用言語の設定が日本語のデバイスでしか利用できないサービスで、iOS 11にアップデートしたら動作しなくなったという問い合わせが届いたので調べてみたら、どうやらiOS 11からNSLocaleの仕様が変更されたらしいことが分かった。

NSLocale.current.identifier

iOS 10以前はjp_JPで取得されていたものが、iOS 11ではen_JPで返ってくるケースがある。

ググってもあんまり盛り上がってないのがちょっと不思議なんだが、唯一見つけた内容がこちら。

抜粋すると

  • iOS 10以前は[NSLocale currentLocale]はアプリのローカライズは関係なく端末の言語設定を直接参照していた
  • iOS 11において[NSLocale currentLocale]はアプリのローカライズしてる言語しか返さなくなった
  • もしアプリが英語しかローカライズしてない場合(デフォルト)は、端末でどんな言語を設定してもcurrentLocaleは英語しか返さない

実際に手元で検証した結果もまとめてみた。

iPhoneの使用言語設定 アプリのローカライズ NSLocaleLanguageCode
1. 日本語, 2. 英語 English en
1. 日本語, 2. 英語 English, Japanese ja
1. 日本語, 2. 中国語 English en
1. 日本語, 2. 中国語 English, Japanese ja
1. 日本語 English ja

stackoverflowで指摘されてる通りの結果になったことが分かる。 公式のリンクはまだ見つかってないようだが、検証結果から見てもどうやら本当ぽい。
実際の検証結果から見ると、iPhoneの使用言語が1つしか選択されてない場合はローカライズされてなくてもその言語が返ってくるぽい。紛らわしい。

つまり端末の設定言語をロジックで利用するようなアプリは、ロジックの対象にしてる言語がアプリでローカライズされているかiOS 11からは注意する必要ある。

今更ぽいけどJenkinsのPipelineの環境構築してみた

仕事でiOS SDKのテスト・ビルドをJenkinsでGithub Pull Request BuilderとかBitbucket Pull Request Builderとかのプラグイン使いながらなんとか構築した途端にJenkins Pipelineの存在を知ってしまったので軽く落胆しながらもローカルのMac PCで動かすまでの環境構築をしてみました

Jenkinsインストー

Homebrewでインストールしてみる

$ brew search jenkins
homebrew/versions/jenkins-lts                                       jenkins                                                             jenkins-job-builder
Caskroom/cask/jenkins-menu

$ brew install jenkins
==> Using the sandbox
==> Downloading http://mirrors.jenkins-ci.org/war/2.54/jenkins.war
==> Downloading from http://ftp.yz.yamagata-u.ac.jp/pub/misc/jenkins/war/2.54/jenkins.war
######################################################################## 100.0%
==> jar xvf jenkins.war
==> Caveats
Note: When using launchctl the port will be 8080.

To have launchd start jenkins now and restart at login:
  brew services start jenkins
Or, if you don't want/need a background service you can just run:
  jenkins
==> Summary
🍺  /usr/local/Cellar/jenkins/2.54: 7 files, 69.9MB, built in 16 seconds

Jenkins起動

とりあえず動作確認したいだけなのでjenkinsコマンドで起動してみる

$ jenkins                                                                                                                                                                     [~]
Running from: /usr/local/Cellar/jenkins/2.54/libexec/jenkins.war
webroot: $user.home/.jenkins

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

********************************

This may also be found at: /Users/toru.furuya/.jenkins/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************

ブラウザでlocalhost:8080にアクセスして推奨プラグインをインストールする

https://gyazo.com/13b55d5e9971dfde507f21cb91684440

Jenkins Job作成

新規ジョブ作成からGithub Organizationsを選択してジョブ作成する

https://gyazo.com/b130a0f77b56ad8c5a78412f20ed423a

Scan credentialsは追加ボタンからGithubのusername/passwordを入力して新規作成する。 Credentialが不正だとInvalid的なメッセージが出てくるので分かりやすい

Jenkinsfile作成

2通りの文法があるらしい。今回はとりあえず最近追加された方のDeclarative方式にしといた。詳細はリンクを参照

https://jenkins.io/doc/book/pipeline/jenkinsfile/

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}

githubにサンプル用のレポジトリ作成してJenkinsfileをcommit

https://github.com/torufuruya/pipeline-sample

Scan実行

Scanログ見てるとこんな感じのがずらーっと流れてくる。どうやらサンプル用のレポジトリを見つけてくれたぽい

Proposing pipeline-sample
Looking up torufuruya/pipeline-sample
  Getting remote pull requests...

  0 pull requests were processed

  Getting remote branches...

    Checking branch master
      ‘Jenkinsfile’ found
    Met criteria

  0 branches were processed (query completed)

Done examining torufuruya/pipeline-sample

Scanが終わるとこんな感じでJenkinsファイルを配置したレポジトリが管理できるようになった。超簡単

https://gyazo.com/535b034ab52b6b43e01ed9994fcc3fb4

Github Enterpriseでの利用

Jenkinsの管理 > システムの設定 > GitHub Enterprise Servers を追加する。Nameは任意のものでOkay

https://gyazo.com/a41ddbc526c5cc89838d3495f1fcd43f

Job作成は最初と全く同じ手順で行うけど、Jenkinsのシステム設定を変更したことによりここでProjectsにAPI endpointの項目が追加される。でさっき作成したGithub Enterprise用のものを選択して再度Credentialsを作成して完了

https://gyazo.com/1c8e8e720a28afd4c8e8d105fdd966c0

Github EnterpriseのレポジトリにJenkinsfile配置してScan実行

Proposing pipeline-sample
Looking up toru-furuya/pipeline-sample
  Getting remote pull requests...

  0 pull requests were processed

  Getting remote branches...

    Checking branch master
      ‘Jenkinsfile’ found
    Met criteria

  0 branches were processed (query completed)

Done examining toru-furuya/pipeline-sample

https://gyazo.com/7a5c389b75773ca7ce99537810aeafac

後記

めちゃくちゃ簡単。恐ろしく簡単。今までJenkinsのWEB UIでぽちぽちしながらメンテしてたジョブたちがコードで管理されると思うと嬉しさしかない。はやくテストとか実行したい。わくわく

以下のサイトを参考にさせていただきました

AWSome Day Tokyo に参加してきた

先週の水曜日、仕事に行かずに早起きして大崎へ。目的はこのイベント。

AWSの導入を検討してたりAWS使い始めてみようかなという人のためのイベント。僕もプライベートでEC2, Route53, AMIだけ使ってWordPressのブログ作ったことあるくらいなので例に漏れず。

Awsome Day Tokyo 2017 行ってきた · GitHub

有給使わず一応仕事として参加したので会社のエンジニアにシェアするようにメモったもの。当日行ってみたら机が用意されておらず割と1人1人のスペースが狭めで予想を裏切られたんだけど、PCを足の上に置きながらなんとか全セッション気になったところだけメモりました。(右隣の人が午前中だけで帰られて端の席空いたのでちょっと余裕できて助かった)MacBookPro17インチでかいからMacBook13インチ切実にほしい。

内容としてはもう既に100を超えてると噂のAWSのサービス群の簡単な紹介と、EC2, S3, RDSの基礎的な話と、IAMのセキュリティ関連な話と、AutoScalingとかその他管理ツール系の話がありました。サービス群で紹介された人工知能系のサービス(Lex, Polly, Rekognition)には「もうこれジャービス*1じゃん!ジャービスはよ!」と胸が高鳴りました。

胸が高鳴ったといえば、IAMの認証情報がもし盗み取られたらビットコインの採掘に使われてるという話もw。

ハッカーじゃなくてクラッカーだろ、っていうツッコミはさておき、

これは極端な例だと思うかもしれないが、オーストラリアのセキュリティ専門家が先月に実施したGitHubの検索では、約1万件のAWS 認証情報が発見されている。

ソースコードの中に認証情報入れちゃ、ダメ。ゼッタイ。 IAMロール周りの話は今まで全く理解してなかったのでこの講演を聞いて理解できて良かった。今回の一番の収穫かもしれないくらいに。講師の大村さんのしゃべりが上手だったのが大きい。プライベートで使ってるAWSはルートアカウントで操作してたからすぐにIAMユーザ作ろうと誓いました。

あとはAmazon Trusted Advisorがこれ便利だなーという印象でした。ビジネスサポートプランかエンタープライズサポートプランじゃないと全ての機能は使えないぽいんだけど、AWS使ってる人は一度使ってみると面白いと思います。僕も早速会社で使ってるAWSで試してみましたが色々とアドバイスをくれました。もう実運用されてるサービスだけど「即時対応が推奨されるチェック項目」がいくつか出て来てしまってwktkが止まりませんでした。

AWS Summitの申し込みも始まりましたね。

Xcode8でも3rdpプラグインが使える件

サードパーティって長いので3rdp

tl;dr

  1. XVim様様
  2. https://github.com/alcatraz/Alcatraz/issues/498
  3. Appleの思想に反するので責任は取れない(自己責任でお願いします)

経緯

ご存知の通りXcode8になってからサードパーティ製のプラグインが使えなくなった。

XcodeGhostというマルウェアが見つかったことが原因? http://researchcenter.paloaltonetworks.com/2015/09/more-details-on-the-xcodeghost-malware-and-affected-ios-apps/

By analysis, XcodeGhost also modified this file in Xcode to control the linker: Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/Contents/Resources/Ld.xcspec

In Xcode, this Ld.xcspec file contains configurations used by the ld linker. In the end of this file, the definition of the “DefaultValue” variable was changed by XcodeGhost by appending a string of: -force_load $(PLATFORM_DEVELOPER_SDK_DIR)/Library/Frameworks/CoreServices.framework/CoreServices

自分もAlcatrazやXVimやVVDocumenterと色々とお世話になっていたから使えなくなった途端開発効率落ちまくりで困った。(Xcode8からドキュメント機能がデフォルトで使えるようになっているの今日知った…)

けど良く考えたらXVimは公式のGithubでXcode8へのインストール方法示してるよなー。あれ?じゃあ他のプラグインもいけんのでは?と思ってやってみたらいけた。

方法

Alcatrazを例に

  1. XVimの公式Githubに記載してあるXcode8にインストールする方法の通りXcodeを自己証明書で署名し直す
  2. Alcatrazをインストールする
  3. (Xcode8.2使ってる場合は)AlcatrazのInfo.plistにXcode8.2のUUID追加する
  4. Xcodeを再起動して出てくるポップアップでLoad Bundle選択する

1. Xcodeの自己署名

MakeXcodeGr8Againというプロジェクトを利用すれば、これ1発でもいけるらしい(試してはない)。 MakeXcodeGr8Again = Make Xcode Great Again って名前が粋ですね。

$ export APP=/Applications/Xcode.app; curl -fsSL https://raw.githubusercontent.com/alanhamlett/MakeXcodeGr8Again/master/selfsign.sh | bash

参考:https://github.com/alcatraz/Alcatraz/issues/498#issuecomment-280546599

2. Alcatrazをインストールする

$ curl -fsSL https://raw.github.com/alcatraz/Alcatraz/master/Scripts/install.sh | sh

3. (Xcode8.2使ってる場合は)AlcatrazのInfo.plistにXcode8.2のUUID追加する

以下のコマンド1発で全プラグインのInfo.plistを更新できる。やってることはPlug-ins/下のInfo.plistを総なめしてXcode.app/Contents/Info.plistのDVTPlugInCompatibilityUUIDの配列を各プラグインのInfo.plistに上書きしてる。

$ find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist -maxdepth 3 | xargs -I{} defaults write {} DVTPlugInCompatibilityUUIDs -array-add `defaults read /Applications/Xcode.app/Contents/Info.plist DVTPlugInCompatibilityUUID`

プラグイン側でXcode最新版のUUIDを入れてくれてればこの作業はいらないんだけど、まあプラグインはもう更新されないでしょうということで新しいプラグインをインストールする度に上記のコマンドを叩けばいいと思う。(ちなみにAlcatrazはXcode8.1までUUIDが登録されてたからXcode8.2のUUID登録のPR出しといた #511

参考:https://github.com/alcatraz/Alcatraz/issues/498#issuecomment-263507135

4. Xcodeを再度開いて出てくるポップアップでLoad Bundle選択する

以上でXcode8.2にAlcatrazが帰って来た!

とはいえ

セキュリティ的にプラグイン使うのはあまり良くなさそう。
XVimがXcode Source Editor Extensionで作り直されるの待とう。
https://github.com/XVimProject/XVim/issues/964

AWSでWordPressブログを開設しました

英語でブログ書きたいなと思ってWordPressで作りました。

markdownで書けることとコードのシンタックスハイライトが使えることあたりを判断材料にしてgithub.ioBloggerWordPressで迷ったんだけど

デザインのテーマがたくさんあって自由にできそうっていうのと、AWSを使ってみたくて、AWSでWorsPressのサイトを立ち上げる方法がウェブ上にたくさん公開されてたのが大きな決め手となった。

Amazonが公式にドキュメントまで用意してくれちゃってて至れり尽くせり。

WordPress ウェブサイトを構築する

やったこと

ドメインの購入

AWSドメイン購入するとDNSの設定まで一括でやってくれるみたいだったんだけどお名前.comのがちょっと安かったからお名前.comで購入。.netが1年間で755円だったので.netに決定。生まれて初めてのドメイン。感慨深い。

EC2のキーペアの登録(重要!)

マニュアルでは「キーペアを選択しないで起動」になってるから何も知らずに言われるがままブログ作ってったら後でsshできない罠に陥る。EC2のインスタンスを起動する前に作成してローカルに秘密鍵のダウンロードまでしておくといいと思う。

EC2インスタンスの起動

BitnamiというAMIを利用する。

DNSのネームサーバをRoute53に変更

ネームサーバはお名前.comで、WordPressをホストしてるサーバがAWSなのでこのままだとブログが見れない。tofucodes.netドメインAWSのサーバをつなぐ作業。この記事を参考にしました。

qiita.com

自分ここでけっこう躓いたので設定をチラリ。

Route53の設定https://i.gyazo.com/b02c5f98e63231ab95e322c395beaaf1.png

お名前.comの設定 https://i.gyazo.com/4f69a53232a0ec11066e65c26e80479b.png

Before

$ nslookup -type=ns tofucodes.net                                                                          [~]
;; Got recursion not available from 2404:1a8:7f01:b::3, trying next server
;; Got recursion not available from 2404:1a8:7f01:a::3, trying next server
Server:         192.168.1.1
Address:        192.168.1.1#53

Non-authoritative answer:
tofucodes.net      nameserver = dns2.onamae.com.
tofucodes.net      nameserver = dns1.onamae.com.

Authoritative answers can be found from:
dns2.onamae.com internet address = 163.44.76.150
dns1.onamae.com internet address = 163.44.76.136

After

$ nslookup -type=ns tofucodes.net                                                                          [~]
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
tofucodes.net      nameserver = ns-1431.awsdns-50.org.
tofucodes.net      nameserver = ns-2044.awsdns-63.co.uk.
tofucodes.net      nameserver = ns-476.awsdns-59.com.
tofucodes.net      nameserver = ns-722.awsdns-26.net.

Authoritative answers can be found from:

おまけ

Google Public DNS

Google Public DNSごいすー!
Macのシステム環境設定でDNSサーバに8.8.8.8設定したらnslookupですぐ見つけられた。

bitnamiのバナー消す方法

BitNamiのAMIでEC2のインスタンスを作るとWordPressのページの下の方にBitNamiのバナーが常時表示されてしまう。これ出っぱなしだとだいぶイケてないので消す方法です。

# ローカル
$ ssh -i ***.pem bitnami@ecX-XX-XX-XXX-XXX.compute-1.amazonaws.com

# EC2
$ sudo /opt/bitnami/apps/wordpress/bnconfig --disable_banner 1
$ sudo /opt/bitnami/ctlscript.sh restart apache

ということで

とりあえずはAWSの無料期間である1年間、英語ブログも更新していくのが目標。

追記

今の状態だとEC2インスタンス破棄した瞬間WordPressの設定もブログデータも全部ふっとぶからRDSとか使った方がいいのかな。やるなら今のうちだな…

生まれて初めて海外のエンジニアの求人に応募してみた

先日stackoverflowでiOS Developerの募集をしている2件の求人に応募してみた。

1週間くらい時間をかけて英語でResume(CV)とCoverLetterを書いた。

作成にあたってはこのサイトを参考にした。

書きながら今の会社に就職してからの5年間を振り返ってみて、他の企業にとって価値のある技術を自分が提供できるのかけっこう悩んだ。

全くの未経験で新卒入社して、いろいろなプロジェクトにアサインされて、

PHP, MySQL, CoffeeScript, JavaScript, TypeScript, Objective-C, Swift, Rubyを使いいろいろな仕事をさせてもらったけど、

転職にあたってインパクトのある技術的な目玉商品みたいなものは持ってないと感じた。

プライベートでオープンソースにコントリビュートしてるわけでもないし。

つまり、アピールできる技術的トピックを5年間で何一つ手に入れられてなかったことに愕然とした。

それでもこの2年間はiOS開発に集中してきたし、iOSアプリは仕事で2つプライベートで1つリリースしたし、SDK(framework)も1から開発した経験があったから、iOS開発ではそれなりに役に立てる自負はあった。

書類選考くらいは通過できるかな?って淡い期待を抱いていた。

1週間後、応募した2件からお祈りメールが届いた。

6年ぶりに受け取ったお祈りメール。なんだか懐かしい。

コンピュータサイエンスの学士も持ってないし、オープンソースにも貢献してない、

そんな20代後半のエンジニアはどこからも必要とされない人間なんじゃないか。

絶望に打ちひしがれながら、明日からまた仕事だ。