2015年12月8日火曜日

Macにhomebrewでdocker toolbox入れてredis動かしてみた

最近はやりのdockerを試したかったので、Macにhomebrewで入れてみました。

まずはhomebrewを最新にして、検索。ちゃんと出てきた。
$ brew update
$ brew search dockertoolbox
Caskroom/cask/dockertoolbox

homebrewでdockertoolboxをインストール。
一緒にvirtualboxもインストールされた。
LaunchpadにインストールされたvirtualboxとDocker Quickstart TerminalとKitematicが配置されている。
$ brew install Caskroom/cask/dockertoolbox
==> Installing brew-cask from caskroom/homebrew-cask
Error: brew-cask-0.55.0 already installed
To install this version, first `brew unlink brew-cask'
==> brew cask install Caskroom/cask/dockertoolbox
==> Satisfying dependencies
==> Installing Cask dependencies: virtualbox
virtualbox ...
==> Downloading http://download.virtualbox.org/virtualbox/5.0.10/VirtualBox-5.0.10-104061-OSX.dmg
######################################################################## 100.0%
==> Running installer for virtualbox; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are ignored.
Password:
==> installer: Package name is Oracle VM VirtualBox
==> installer: Installing at base path /
==> installer: The install was successful.
🍺  virtualbox staged at '/opt/homebrew-cask/Caskroom/virtualbox/5.0.10-104061' (4 files, 87M)
done
complete
==> Downloading https://github.com/docker/toolbox/releases/download/v1.9.0d/DockerToolbox-1.9.0d.pkg
######################################################################## 100.0%
==> Running installer for dockertoolbox; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are ignored.
==> installer: Package name is Docker Toolbox
==> installer: Installing at base path /
==> installer: The install was successful.
🍺  dockertoolbox staged at '/opt/homebrew-cask/Caskroom/dockertoolbox/1.9.0d' (204M)

まずはdockerを動かすホストマシンをvirtualboxに設定して作成。
$ docker-machine create --driver virtualbox default
Creating CA: /Users/xxx/.docker/machine/certs/ca.pem
Creating client certificate: /Users/xxx/.docker/machine/certs/cert.pem
Running pre-create checks...
Creating machine...
Waiting for machine to be running, this may take a few minutes...
Machine is running, waiting for SSH to be available...
Detecting operating system of created instance...
Provisioning created instance...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
To see how to connect Docker to this machine, run: docker-machine env default

作成したものはここにファイルが作られるようです
$ ls -al ~/.docker/machine/machines/default/
total 81344
drwx------  13 xxx  staff       442 11 17 12:23 .
drwx------   3 xxx  staff       102 11 17 12:22 ..
-rw-r--r--   1 xxx  staff  31457280 11 17 12:22 boot2docker.iso
-rw-r--r--   1 xxx  staff      1038 11 17 12:23 ca.pem
-rw-r--r--   1 xxx  staff      1074 11 17 12:23 cert.pem
-rw-------   1 xxx  staff      2943 11 17 12:24 config.json
drwx------   5 xxx  staff       170 11 17 12:23 default
-rw-------   1 xxx  staff  10158080 11 17 12:25 disk.vmdk
-rw-------   1 xxx  staff      1679 11 17 12:22 id_rsa
-rw-------   1 xxx  staff       381 11 17 12:22 id_rsa.pub
-rw-------   1 xxx  staff      1679 11 17 12:23 key.pem
-rw-------   1 xxx  staff      1675 11 17 12:23 server-key.pem
-rw-r--r--   1 xxx  staff      1123 11 17 12:23 server.pem

docker-machineの状態を見てみると、起動しているようです。
$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM
default   -        virtualbox   Running   tcp://192.168.99.100:2376 

次に以下のコマンドを実行する。特に何も表示はされません。
$ eval "$(docker-machine env default)"

続いてredisのコンテナイメージを持ってきます。
$ docker pull redis:3.0.5
3.0.5: Pulling from library/redis
141ed44bf003: Pull complete 
e2e4a15f0f05: Pull complete 
bde7d1a2c3f2: Pull complete 
30fde03bce2b: Pull complete 
57f91d220af6: Pull complete 
85decd8581c3: Pull complete 
dc733a1e5ab9: Pull complete 
9702d439a536: Pull complete 
1f7c80b73750: Pull complete 
f947b6a7c248: Pull complete 
9dc7228b2288: Pull complete 
53ba438d7aa7: Pull complete 
fad954217030: Pull complete 
a06a2b579a40: Pull complete 
05239cc42ab0: Pull complete 
fd59e10ac3c9: Pull complete 
7159515e5dce: Pull complete 
Digest: sha256:5b408fc3c12a800ca36ca243f9bdcc3f8efed8608572a509b7fbdcbef3e76b8c
Status: Downloaded newer image for redis:3.0.5

Dockerfileを作成します。
FROM redis:3.0.5

# log file
RUN touch /var/log/redis.log && chmod 755 /var/log/redis.log && chown redis:redis /var/log/redis.log

# conf file
ADD redis.conf /tmp/redis.conf
RUN mkdir -p -m 755 /usr/local/etc/redis && chown redis:redis /usr/local/etc/redis && cp /tmp/redis.conf /usr/local/etc/redis && chown redis:redis /usr/local/etc/redis/redis.conf && rm /tmp/redis.conf

EXPOSE 6379

CMD ["redis-server","/usr/local/etc/redis/redis.conf"]

redis.confも同じディレクトリに配置します。
vim redis.conf
適切な内容を記述

コンテナイメージを作成します。
$ docker build -t redis:3.0.5 .
Sending build context to Docker daemon 44.54 kB
Step 1 : FROM redis:3.0.5
 ---> 7159515e5dce
Step 2 : RUN touch /var/log/redis.log && chmod 755 /var/log/redis.log && chown redis:redis /var/log/redis.log
 ---> Running in afdf261202ed
 ---> 779d22d0e041
Removing intermediate container afdf261202ed
Step 3 : ADD redis.conf /tmp/redis.conf
 ---> 69591881edca
Removing intermediate container d64a9c967b0f
Step 4 : RUN mkdir -p -m 755 /usr/local/etc/redis && chown redis:redis /usr/local/etc/redis && cp /tmp/redis.conf /usr/local/etc/redis && chown redis:redis /usr/local/etc/redis/redis.conf && rm /tmp/redis.conf
 ---> Running in 9304d5f32d59
 ---> 250ea953a1a9
Removing intermediate container 9304d5f32d59
Step 5 : EXPOSE 6379
 ---> Running in 2d3f10877d3b
 ---> bec30d81d359
Removing intermediate container 2d3f10877d3b
Step 6 : CMD redis-server /usr/local/etc/redis/redis.conf
 ---> Running in 28d5ce42be84
 ---> e5d21ff31a69
Removing intermediate container 28d5ce42be84
Successfully built e5d21ff31a69

コンテナを起動する。
Unable to findとか言われてるので怪しいのだが、
ちゃんと起動していた。。。
$ docker run -d --name redis_server redis:3.0.5
Unable to find image 'redis:3.0.5' locally
3.0.5: Pulling from library/redis
141ed44bf003: Pull complete 
e2e4a15f0f05: Pull complete 
bde7d1a2c3f2: Pull complete 
30fde03bce2b: Pull complete 
57f91d220af6: Pull complete 
85decd8581c3: Pull complete 
dc733a1e5ab9: Pull complete 
9702d439a536: Pull complete 
1f7c80b73750: Pull complete 
f947b6a7c248: Pull complete 
9dc7228b2288: Pull complete 
53ba438d7aa7: Pull complete 
fad954217030: Pull complete 
a06a2b579a40: Pull complete 
05239cc42ab0: Pull complete 
fd59e10ac3c9: Pull complete 
7159515e5dce: Pull complete 
Digest: sha256:5b408fc3c12a800ca36ca243f9bdcc3f8efed8608572a509b7fbdcbef3e76b8c
Status: Downloaded newer image for redis:3.0.5
ea875fae4d9d6c70b8a4393b5d2dff0795776b3fa21eb929628d68d5b602432c

コンテナが起動していることを確認。
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
2d17e74d25e2        redis:3.0.5         "/entrypoint.sh redis"   14 minutes ago      Up 14 minutes       6379/tcp            redis_server

redisに接続するため、接続するIPを調べる
$ docker-machine ip default
192.168.99.100 

telnetで接続してみたら繋がらなかった
$ telnet
telnet> open 192.168.99.100 6379          
Trying 192.168.99.100...
telnet: connect to address 192.168.99.100: Connection refused
telnet: Unable to connect to remote host
telnet> quit

コンテナを停止して削除し、ポートを指定してコンテナを再度作り直す
$ docker stop redis_server
redis_server
$ docker rm redis_server
redis_server

$ docker run -d --name redis_server -p 6379:6379 redis:3.0.5
f59a2531a0c46a780b78084c7e0b75508750d472532df62ff44b62305613d45a

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
f59a2531a0c4        redis:3.0.5         "/entrypoint.sh redis"   3 seconds ago       Up 2 seconds        0.0.0.0:6379->6379/tcp   redis_server

今度はtelnetで接続できた
$ telnet
telnet> open 192.168.99.100 6379
Trying 192.168.99.100...
Connected to 192.168.99.100.
Escape character is '^]'.
INFO
$2067
# Server
redis_version:3.0.5
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b26e24044465030c
redis_mode:standalone
os:Linux 4.1.12-boot2docker x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.7.2
process_id:1
run_id:23e122e716026918b41998ce6cec3a4af9590fe6
tcp_port:6379
uptime_in_seconds:178
uptime_in_days:0
hz:10
lru_clock:4902862
config_file:/usr/local/etc/redis/redis.conf

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:296832
used_memory_human:289.88K
used_memory_rss:9207808
used_memory_peak:296832
used_memory_peak_human:289.88K
used_memory_lua:36864
mem_fragmentation_ratio:31.02
mem_allocator:jemalloc-3.6.0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1447743260
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_current_size:0
aof_base_size:0
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

# Stats
total_connections_received:1
total_commands_processed:0
instantaneous_ops_per_sec:0
total_net_input_bytes:6
total_net_output_bytes:0
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0

# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:0.17
used_cpu_user:0.18
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace


参考URL
https://docs.docker.com/v1.8/installation/mac/
https://blog.docker.com/2015/08/docker-toolbox/
http://qiita.com/rubytomato@github/items/dd2e605706b03ad60f00

2015年12月1日火曜日

CtoCサービスの開発の裏側を公開! プロダクト責任者、CTOが全て語ります! に参加してきました

こちらのイベントに参加してきました。
CtoCサービスの開発の裏側を公開! プロダクト責任者、CTOが全て語ります!
http://connpass.com/event/22515/

メルカリ、フンザ、ココナラのCOO、CTOの方々の話を聞いたり、
実際にCtoCのサービスをやってる方々と話す機会を設けていただき、
自分もCtoCのサービスをやってる身としては、有意義な時間を過ごすことができました。

つらつらとメモったことについて、載せていきます。

◯Founderが語る、プロダクトへの想い
・メルカリ
 従業員200名(日米合計)
 半数以上がカスタマーサポート
 エンジニア、デザイナー40名(9割はアメリカ)

ローンチのときのエピソード
 開発6ヶ月
 ios/android両方
 クオリティを下げないように機能を削った
  検索ができない→想定以上に出品→ SQLのlikeでとりあえず→ちゃんと検索作る
  振り込み申請できない→ アプリのアップデートでできればよいよね

 CtoCこのモデルは最初きつい、地道にチューニングしていく。一点越えるとわーっと増えていく。

中長期の話、チャレンジしたい話
 アメリカの改修が日本に反映されたり
 メルカリのID使って、メルカリの経済圏でまわしていきたい
 BtoCでもモバイルで新しい体験を作っていきたい

会社のカルチャー
 ウノウ、mixiからの人多め
 go bold

・フンザ
 従業員23名(エンジニア5名)
 mixi子会社
 2015年9月 流通26.5億円

ローンチのときのエピソード
 チケットなので、写真がないので、人気(ひとけ)がない
 KPI2倍ルール→2倍にならないものはやらない
 退会半年間できない

   5ヶ月くらいトラフィックの波が来なかった
  転機 サマーソニックのチケットだけがやたら売買されている →恩としてサマソニに協賛(1億円)

 CtoCの機能でブーストかかるようなものはない

中長期の話、チャレンジしたい話
 スマホの中には音楽の情報がつまっている
  itunesとチケットキャンプの情報をマッチングして、プッシュしたりとか。
  位置情報とマッチングしてプッシュしたりとか。

会社のカルチャー
 少数精鋭、一人当たりの生産性、責任

・ココナラ
 従業員20名
 ユーザー数20万人、取引件数 26000/月

ローンチのときのエピソード
 クローズドベータでローンチ
  →一回作り直している wantedlyモデルw
  長い相談してると時給がさがる
   文字を制限したら非難轟々
   →作り直す
 買い気
  コミュニテイっぽい雰囲気→買える感なくなる(商品に見えない)→ボタンとかECっぽくしてみる
 プライシング
  同じ内容でも価格が違うときに適正がわからない
  わかりやすいようにワンコインで

  出品者が増えて慣れてきて窮屈になってきた→価格をあげていった

中長期の話、チャレンジしたい話
 プロダクトを作ったときのモデルを見直した。
 モデルに即した形に機能を減らしたり、fine tuningしたりしてる。
 アプリに。

会社のカルチャー
 サービスに共感してるメンバー
 難しいところが好きみたいなメンバー
 サービスを伸ばすんだという気概があるメンバー
 言いたいことを言って、それがすべてサービスのためになる会社


◯CtoCサービスの裏側
・メルカリ
プロダクト立ち上げ時のチーム体制や採用について
 最初は知り合いに声をかけてウノウのつながりやjingaのつながり
 最初のリリース時も20人いないくらい
 知り合いが知り合いを呼んで
 スキルがあるだけではだめで、文化がマッチするかどうかも含めて

利用している技術の選定
 一番自信のあるものにする
 一人で作っていくものではないので、同じレベルで開発できる人が集められる技術を使う
 PHP
 学習コストが低いもの

機能追加や機能改善の判断軸はどこに置いているか?サービス設計の思想などあれば。
 ディレクターとエンジニアが近いところにいる

会社や開発チームをまとめるためにやっていること
 全体に対して何かをやるのではなく、一人一人に対して話すことを増やしている
 10人以下なら意思疎通は簡単だが、どんどん増えてくとこうやったほうがいい

エンジニアのキャリアパスについて
 急激に成長している会社に身を置くのが大事

 どういうエンジニアがいるか
  平均年齢が高い
  10年前とかにばりばりネット企業で活躍していた

技術的に苦労した点
 そんなにない
 ゲームの方が書き込みとか多くて難しい
 CtoCは安定的に動かす、そんなに難しくない

どこまでオペレーションで済ませ、どこから自動化するかの判断のポイント
 まず手動でやることを考え、耐えられなくなったら自動化
 最初にめっちゃがんばって自動化作っても、手でやった方が早いってなるともったいない
 デフォルトは人間にがんばってもらう

・フンザ
プロダクト立ち上げ時のチーム体制や採用について
 元同僚とか紹介などつながりで。
 初めて半年で1人、1年で1人増えた
 カルチャーにマッチするかを重視

利用している技術の選定
 python django
 AWS
 MySQL
自信を持って使える技術

機能追加や機能改善の判断軸はどこに置いているか?サービス設計の思想などあれば。
 技術的負債を残さないようにしたい
  新しく入った人にがっかりさせたくない
 できませんを絶対に言わない

 納得できないことがあったら、とことん話あって、納得して仕事する

会社や開発チームをまとめるためにやっていること
 チームのモチベーションを下げることは、リーダー的な人のダブルスタンダードな振る舞い

エンジニアのキャリアパスについて
 1つの技術を極めるのが大事。自分の拠り所になる技術があるからサービスが作れたと思う
 限界を定めないことが大事。
 webからアプリにの流れは続く
 データ解析とかやれる人とかいい。

技術的に苦労した点
 どうやってユーザーの書き込みなどをエレガントに監視していくか
  禁止ワードみたいな
 普通の人がどう使っているかみたいなところが難しい

どこまでオペレーションで済ませ、どこから自動化するかの判断のポイント
 手動か自動かだけでなく、手動でやっていることをいかに短くやれるかも考慮
 手動でのエラーレートが高いものは自動化を考える

・ココナラ
プロダクト立ち上げ時のチーム体制や採用について
 基本1人でシステム作ってる
 内製にこだわる
 一部外注したり、知り合いのフリーランスにお願いしたりとか
 ないところから作っていくのを楽しめるメンバーかが重症

利用している技術の選定
PHP CakePHP
MySQL
最初に担当してたエンジニアが一番得意な言語

機能追加や機能改善の判断軸はどこに置いているか?サービス設計の思想などあれば。
 数字を見て根拠を出してやるかを検討する
 やった後にちゃんと数値を見て反省を行う

会社や開発チームをまとめるためにやっていること
 みんなが目指すべき目標を共有していく
 みんなで一緒にランチを食べるとかも意外と重要

エンジニアのキャリアパスについて
 単に人並みにできるってことがいくらあっても市場的にはつらいかな
 長い時間を培った技術などをつけて差別化していかないとつらい
 10年たっても変わらない技術などを身につけていく

技術的に苦労した点
 いかに運用コストをかけないようにまわしていくかとか。
 決済手段を幅広く用意しているが、各社思想が違うのでどうモデルに組み込んでいくかとか。

どこまでオペレーションで済ませ、どこから自動化するかの判断のポイント
 あえて管理ツールでできないようにしてるフローも残してたりする

2015年10月29日木曜日

Deviseとomniauth-facebookでFacebook認証したときに元いたページに戻りたい

Deviseとomniauth-facebookでFacebook認証でのログインを実装してたのですが、
元いたページに戻れなかったので、どうやるのか調べました。

修正前
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def after_sign_in_path_for(resource)
    super
  end
end

いろいろ調べてみたところ、ちゃんとセットしているところがあったので、
そこでセットしている request.env['omniauth.origin'] から取得するようにしました。
一応、他サイトに飛ばないように自分のサイトかどうかはチェックしています。
修正後
def after_sign_in_path_for(resource)
  referer = request.env['omniauth.origin']
  if referer.present? && referer.starts_with?(request.protocol + request.host_with_port)
    referer
  else
    super
  end
end


参考URL
https://github.com/intridea/omniauth/issues/306
http://stackoverflow.com/questions/11355928/devise-redirect-to-previous-page-after-authenticating-user-request-referer-re
https://github.com/intridea/omniauth/blob/master/lib/omniauth/strategy.rb#L213
http://blog.yasuoza.com/2012/08/16/devise-omniauth-facebook/

2015年10月23日金曜日

IE10/11でjqueryのajaxで正しくフォームが送れない

jqueryのajaxを使ってformのsubmitを使っていたら、
エラーが出るユーザーがいるとのことだったので、調べたところ
Internet Explorer10/11を使っているときのバグだったようです。

formはこんな感じで組んでいました。
<form accept-charset="UTF-8" action="/test" method="post">
<input class="datepicker form-control" id="test" name="test[dates_attributes][201510000][date]" placeholder="日付を選択してください" readonly="readonly" type="text" value="2015-10-23" />
<input id="dates_attributes_201510007__destroy" name="test[dates_attributes][201510000][_destroy]" type="checkbox" value="1" />
<a class="save-dates-btn">更新</a>
</form>

ajax部分もよくある形で組んでいました。
      $(document).on("click", '.save-dates-btn', function(event) {
        var form = $(this).parents('form:first');
        var formData = new FormData( form[0] );
        $.ajax({
          type: "POST",
          url: "#{update_dates_path}.json",
          data: formData,
          processData: false,
          contentType: false,
          error: function(data){
            console.log("error");
          },
          success: function (data) {
            console.log("success");
          }
        });
      });

サーバーはrailsを使っていて、以下のエラーが出ていました。
!! Unexpected error while processing request: bad content body

調べていったところ、
IE10/11ではformの中の最後のinputがチェックボックスで、それに対してチェックボックスがついてないときに、
ajaxで送るformDataの値がおかしくなるようです。

対策としてはcheckboxが最後にならないようにすればよいようで、
最後にhiddenでもよいのでダミーのパラメータを追加して対応しました。
<input name="dummy" type="hidden" value="1" />


参考URL
https://blog.yorkxin.org/posts/2014/02/06/ajax-with-formdata-is-broken-on-ie10-ie11/

2015年10月1日木曜日

JAWS-UG Meguro #2に参加してきました

先週の話ですが、JAWS-UG Meguro #2に参加してきました。
http://jawsug-meguro.connpass.com/event/18162/

正直、今の会社ではまだ使わないような技術の話ばっかりだったのですが、
今後のためにとてもためになったと思います。

特にmyfinderさんの「今更聞けないストリーム処理のあれとかこれ」の話は、
これからどう入れていこうかなってステージの自分にはすごくためになりました。
発表の資料は↑のイベントページにアップされているので、そちらを見ていただくのがよいです、
要約すると、stream処理ってものはどういうもので、
それを処理するための基盤と技術の選択肢はこういうのがあるよっていうのを、
パターンを提示してくれている発表でした。
実際にどうやってみるかは結局手を動かしてみないとわかんないと思うので、
まずどういうのを試してみるのがいいかってのが判断できるだけでも、
この発表が自分にとってはすごくためになりました。

2015年9月21日月曜日

rubyのaws-sdkでamazonS3のaclを変更する

ユーザーの権限によって画像の公開範囲を制限する必要が出てきたので、
amazon S3のaclを動的に変えるコードを書きました。

s3 = AWS::S3.new
bucket_name = "xxx"
bucket = s3.buckets[bucket_name]
user.user_photos.each do |photo|
  o = bucket.objects[photo.url.path]
  if user.publicly?
    o.acl = :public_read
  else
    o.acl = :private
  end
end

photo.url.pathにはbucket_name以降の/からファイル名までのパスが入ります。

http://akasata.com/articles/292
http://qiita.com/ryo0301/items/791c0a666feeea0a704c
https://github.com/thoughtbot/paperclip/issues/1416

2015年8月25日火曜日

railsのformのselectでclassが当てられない

formの入力画面をrailsで作っていて、プルダウンを使うのにselectを使っていたのですが、
オプションに書かれてるclassを指定してもclassがHTMLに出力されないので調べました。

スケジュール登録での時の部分をslimでこんな感じで書いてました。
= form_for(@profile, :url => { :action => "update_schedule" }) do |f|
= f.fields_for :repeat_schedules do |rpt|
= rpt.select :start_time_hour, options_for_select((Array 0..23).map { |i| format("%02d", i) }, selected: rpt.object.start_time_hour), { class: 'form-control' }
これだとclassが出力されないため、styleが適用されませんでした。
調べたところ、classを書いている{}の前にもう一つ{}を入れるとよいようです。
こんな感じにするとちゃんとclassが出力されるようになりました。
= rpt.select :start_time_hour, options_for_select((Array 0..23).map { |i| format("%02d", i) }, selected: rpt.object.start_time_hour), {}, { class: 'form-control' }


参考URL
http://stackoverflow.com/questions/21338113/cant-add-class-on-select-form-helper-in-rails-4

2015年8月18日火曜日

bootstrapでreadonlyのテキストボックスにcssで色を変える

bootstrapでテキストボックスにスタイルを当ててたのですが、
readonlyにしてる場所がclassでスタイルを設定しても、
bootstrapで指定してるグレーっぽい色から変えられなかったので調べました。

テキストボックスのタグはこんな感じ。v schedule-input-styleにcssで色をいろいろ設定してもbootstrapのデフォルトのやつに上書きされてしまいます。
<input id="user_work_dates_attributes_20158000_work_date" class="datepicker form-control schedule-input-style" type="text" value="2015-08-18" readonly="readonly">

調べたところ、普通にschedule-input-styleにスタイルを設定するのではなく、
以下のように設定すればよいようです。カーソルもデフォルトのものに変えることができました。
input[readonly].schedule-input-style{
  background-color: #ffffff;
  cursor: default;
}


参考URL
http://stackoverflow.com/questions/23812365/force-enabled-look-to-readonly-input-with-bootstrap-css

2015年8月12日水曜日

classにiCheckを指定したらイベントが取れなかったときの対応

iCheckを使ってたら、
そこのチェックボックスをチェックした時にJSのイベント発火させようと思ったら、
すぐには取れなかったので調べた時の対応です。

iCheckのstyleがあたっているチェックボックスでonclickやonchangeの
イベントを拾おうとしましたが、反応しませんでした。
$('.test-checkbox').on('click', function() {
      console.log('aaa');
    });

    $('.test-checkbox').on('change', function() {
      console.log('aaa');
    });

調べたところ、こう書けば良いようです。
公式にも書いてありました。。。
 $('.test-checkbox').on('ifChecked', function(event) {
      console.log('aaa');
    });


参考URL
http://arimo.hatenablog.com/entry/icheck_radio_notwork

2015年8月5日水曜日

railsでrspecのテスト書いてたらparamsではまった件

railsのmodelのメソッドにparamsを渡している処理があったので、
そこのテストをrspecで書いてました。
何も考えずにHashでparamsを作って引数に渡していたら、
Strong Parametersのところで
No explicit conversion of Symbol into Stringのエラー出てしまいました。
ちゃんと調べたら、paramsはHashではなくて、
ActionController::Parametersを使っていました。
rspecではActionController::Parameters.new({})の形でやればうまくいきました。
しょーもない話です、、、

参考URL
http://stackoverflow.com/questions/25374559/no-explicit-conversion-of-symbol-into-string-for-new-records-in-rails-4-0-1-o

2015年7月19日日曜日

MacにhomebrewでAtomを入れた

ちょっと環境を作り変えることになったので、
エディタも変えてみようと思い、homebrewでAtom入れてみました。

Atomはbrew caskで入れられるようなので、
まずは検索してみる。
$ brew cask search atom
No cask found for "atom".

出てこなかったのでcaskをupgradeしてみる。
$ brew upgrade cask
Error: No such file or directory - /usr/local/Cellar/cask

どうやらcaskでは入ってないようなので、何で入っているのか調べてみる。
$ ls /usr/local/Cellar/
autoconf/           makedepend/         pkg-config/         rbenv-default-gems/ readline/           
brew-cask/          mysql/              python/             rbenv-gem-rehash/   ruby-build/         
gdbm/               openssl/            rbenv/              rbenv-gemset/       sqlite/  

brew-caskで入っているようなので、改めてupgradeしてみる。
$ brew upgrade brew-cask
==> Upgrading 1 outdated package, with result:
phinze/cask/brew-cask 0.54.1
==> Upgrading phinze/cask/brew-cask
==> Cloning https://github.com/caskroom/homebrew-cask.git
Cloning into '/Library/Caches/Homebrew/brew-cask--git'...
remote: Counting objects: 2999, done.
remote: Compressing objects: 100% (2902/2902), done.
remote: Total 2999 (delta 117), reused 834 (delta 81), pack-reused 0
Receiving objects: 100% (2999/2999), 5.74 MiB | 3.70 MiB/s, done.
Resolving deltas: 100% (117/117), done.
Checking connectivity... done.
Note: checking out '2fc9d2323950a45549e1d5c4b25481d98726b85c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

==> Checking out tag v0.54.1
🍺  /usr/local/Cellar/brew-cask/0.54.1: 2731 files, 11M, built in 8 seconds

無事にupgradeができたので、Atomの情報が取れるかinfoで確かめてみる。
$ brew cask info atom
atom: 1.0.2
Atom
https://atom.io/
Not installed
https://github.com/phinze/homebrew-cask/blob/master/Casks/atom.rb
==> Contents
  Atom.app (app)
  Atom.app/Contents/Resources/app/apm/node_modules/.bin/apm (binary)
  Atom.app/Contents/Resources/app/atom.sh (binary)

atomの情報が取れたので、installをしてみる。
$ brew cask install atom
==> Satisfying dependencies
complete
==> Downloading https://github.com/atom/atom/releases/download/v1.0.2/atom-mac.zip
######################################################################## 100.0%
==> Symlinking App 'Atom.app' to '/Users/xxxx/Applications/Atom.app'
==> Symlinking Binary 'apm' to '/usr/local/bin/apm'
==> Symlinking Binary 'atom.sh' to '/usr/local/bin/atom'
🍺  atom staged at '/opt/homebrew-cask/Caskroom/atom/1.0.2' (1574 files, 198M)

無事にインストールできた。
シンボリックリンクがユーザーのアプリケーションディレクトリに貼られていて、
/Applications配下には入ってないので、起動するときはLaunchpadとかから起動するのがよさそうです。


参考URL
http://qiita.com/hkusu/items/f41f5566e1040147f1fc

2015年7月13日月曜日

awsのec2インスタンス作成時にruby2.2.2をインストールするユーザーデータ

完全にメモですが、awsでec2インスタンス作るときに、
ruby2.2.2をrbenvで入れてある状態にするユーザーデータです。

#!/bin/bash
yum update -y
yum install -y git
yum install -y gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel libffi-devel libxml2 libxslt libxml2-devel libxslt-devel sqlite-devel mysql-devel
yum install -y patch
 
cd /usr/local
git clone https://github.com/sstephenson/rbenv.git
mkdir -p /usr/local/rbenv/plugins
cd /usr/local/rbenv/plugins
git clone https://github.com/sstephenson/ruby-build.git
 
cat << EOF >> /etc/profile.d/rbenv.sh
export RBENV_ROOT=/usr/local/rbenv
export PATH="\$RBENV_ROOT/bin:\$PATH"
eval "\$(rbenv init -)"
EOF
 
source /etc/profile.d/rbenv.sh
rbenv install -f 2.2.2
rbenv rehash
rbenv global 2.2.2
rbenv version
最後にrbenv versionを入れてないと、最初にログインした時のruby -vが2.2.2にならなかった

参考URL
http://hivecolor.com/id/129

2015年7月6日月曜日

AWSのS3で静的ウェブサイトホスティングするときのバケットポリシー

AWSのS3で静的ウェブサイトホスティングでjsやcssを配信したいと思い、
どこのサイトからでもアクセスされてかまわない形でアクセスを許可したときの
バケットポリシーについて調べました。
AWSのドキュメントにもあるように、以下の記述でうまくいきました。
{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Sid": "PublicReadGetObject",
   "Effect": "Allow",
   "Principal": "*",
   "Action": "s3:GetObject",
   "Resource": "arn:aws:s3:::バケット名/*"
  }
 ]
}

参考URL
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html

2015年6月29日月曜日

gulp.jsでreactjsのuglifyでエラー出たときの対応

gulp.jsでreact.jsで書いたものを圧縮しようとしたときにエラーが出たときの対応です。

まず以下のようなgulpfile.jsを書きました。
var gulp = require('gulp');
var browserify = require('browserify');
var source = require("vinyl-source-stream");
var reactify = require('reactify');
var watchify = require('watchify');
var sass = require('gulp-sass');
var buffer = require('vinyl-buffer');
var plumber = require('gulp-plumber');
var uglify = require('gulp-uglify');
 
gulp.task('browserify', function(){
  var b = browserify({
    entries: ['./src/test.jsx'],
    transform: [reactify]
  });
  return b.bundle()
    .pipe(source('test.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist'));
});

それをbrowserifyしてみたところ、エラーになりました。
$ gulp browserify
[10:26:15] Using gulpfile ~/Documents/github/test/gulpfile.js
[10:26:15] Starting 'browserify'...
 
events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: /Users/xxxx/Documents/github/test/test.js: Streaming not supported

調べたところ、gulp-streamifyを使うとよいようです。
・インストール
$ npm install --save-dev gulp-streamify
 
・requireを追加
var streamify = require('gulp-streamify');

・uglify()をstreamify(uglify())に変更
gulp.task('browserify', function(){
  var b = browserify({
    entries: ['./src/test.jsx'],
    transform: [reactify]
  });
  return b.bundle()
    .pipe(source('test.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('./dist'));
});

修正して実行したらエラー出ませんでした。
$ gulp browserify
[10:29:52] Using gulpfile ~/Documents/github/test/gulpfile.js
[10:29:52] Starting 'browserify'...
[10:29:56] Finished 'browserify' after 3.85 s

参考URL
http://yebisupress.dac.co.jp/2015/02/26/gulp-js%E3%81%A7%E5%BA%83%E5%91%8A%E3%82%BF%E3%82%B0%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E6%95%B4%E3%81%88%E3%82%8B/
https://github.com/hughsk/vinyl-source-stream/issues/1

2015年6月22日月曜日

watchifyでreactjsで書いたものがエラーになる

reactjsで開発することになったので、watchifyで楽しようとしたらエラー出たときの対応です。

watchifyしたときのエラーはこんな感じ
$ watchify src/test.jsx -o dist/test.js -v
Error: Parsing file /Users/xxxx/Documents/github/module/src/test.jsx: Unexpected token (196:8)
196行目は以下の<div>のところ
    render: function(){
      return(
        <div className="item">
調べたところ、-tでモジュールを指定する必要があるようです。
以下の形だとエラー出ませんでした。
$ watchify -t reactify src/test.jsx -o dist/test.js -v
640293 bytes written to dist/test.js (2.10 seconds)

参考URL
http://qiita.com/masato/items/35b0900e3a7282b33bf8

2015年6月15日月曜日

herokuでrake db:migrate:resetするとエラーになる

herokuでdbのmigrateを再実行したかったので、
db:migrate:resetを実行したらエラーになったときの対応です。

実行してみたときのエラーはこんな感じ
$ heroku run rake db:migrate:reset
Running `rake db:migrate:reset` attached to terminal... up, run.7795
FATAL:  permission denied for database "postgres"
DETAIL:  User does not have CONNECT privilege.
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `initialize'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `new'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `connect'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:242:in `initialize'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:44:in `new'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:44:in `postgresql_connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:438:in `new_connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:448:in `checkout_new_connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:422:in `acquire_connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:349:in `block in checkout'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:348:in `checkout'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:263:in `block in connection'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:262:in `connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:567:in `retrieve_connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:113:in `retrieve_connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:87:in `connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/postgresql_database_tasks.rb:8:in `connection'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/postgresql_database_tasks.rb:30:in `drop'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:114:in `drop'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:128:in `block in drop_current'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:275:in `block in each_current_configuration'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:274:in `each'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:274:in `each_current_configuration'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:127:in `drop_current'
/app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/railties/databases.rake:28:in `block (2 levels) in '
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:240:in `call'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:235:in `each'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:235:in `execute'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:201:in `block in invoke_prerequisites'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:199:in `each'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:199:in `invoke_prerequisites'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:178:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:165:in `invoke'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:150:in `invoke_task'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `block (2 levels) in top_level'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `each'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `block in top_level'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:115:in `run_with_threads'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:100:in `top_level'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:78:in `block in run'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling'
/app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:75:in `run'
/app/bin/rake:8:in `
' Couldn't drop db_table FATAL: permission denied for database "postgres" DETAIL: User does not have CONNECT privilege. /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `initialize' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `new' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:651:in `connect' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:242:in `initialize' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:44:in `new' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:44:in `postgresql_connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:438:in `new_connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:448:in `checkout_new_connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:422:in `acquire_connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:349:in `block in checkout' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:348:in `checkout' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:263:in `block in connection' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:262:in `connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:567:in `retrieve_connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:113:in `retrieve_connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:87:in `connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/postgresql_database_tasks.rb:8:in `connection' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/postgresql_database_tasks.rb:17:in `create' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:93:in `create' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:107:in `block in create_current' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:275:in `block in each_current_configuration' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:274:in `each' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:274:in `each_current_configuration' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/tasks/database_tasks.rb:106:in `create_current' /app/vendor/bundle/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/railties/databases.rake:17:in `block (2 levels) in ' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:240:in `call' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:235:in `each' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:235:in `execute' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:201:in `block in invoke_prerequisites' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:199:in `each' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:199:in `invoke_prerequisites' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:178:in `block in invoke_with_call_chain' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:165:in `invoke' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:150:in `invoke_task' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `block (2 levels) in top_level' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `each' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `block in top_level' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:115:in `run_with_threads' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:100:in `top_level' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:78:in `block in run' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling' /app/vendor/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:75:in `run' /app/bin/rake:8:in `
' Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"utf8", "pool"=>5, "database"=>"db_table", "username"=>"user", "password"=>"password", "port"=>5432, "host"=>"hostname"}
調べてみたところ、DBを書き換えるようなコマンドはpermissionエラーになるようになっているようです。
rakeタスクでやらずにpostgresqlを直接操作して削除し、
それからrake db:migrateでやるとよいようです。
$ heroku pg:reset DATABASE
 
 !    WARNING: Destructive Action
 !    This command will affect the app: heroku-host
 !    To proceed, type "heroku-host" or re-run this command with --confirm heroku-host
 
> heroku-host
Resetting DATABASE_URL... done

$ heroku run rake db:migrate


参考URL
http://blog.aripei.com/2013/10/rails-operation-in-heoku.html

2015年6月8日月曜日

ActiveRecordにattr_accessorで定義したものがto_jsonで含まれない

何も考えずにActiveRecordでto_jsonやっていたら、
attr_accessorで定義したものがJSONに含まれてなかったので、
そのときに調べたことを書いていきます。

クラスはこんな感じ
# == Schema Information
#
# Table name: items
#
#  id         :integer          not null, primary key
#  name       :string
#  img        :string
#  price      :integer
#  created_at :datetime         not null
#  updated_at :datetime         not null
#
 
class Item < ActiveRecord::Base
  attr_accessor :view_img_url
end

item = Item.new
item.name = 'なまえ'
item.img = 'test.jpg'
item.view_img_url = 'http://aaa.bbb/ccc/ddd/test.jpg'
item.price = 100
 
p item.to_json
JSONにview_img_urlが含まれていませんでした。
view_img_urlを含むためにはto_jsonの引数にmethods: :view_img_urlを与える必要があります。
p item.to_json(methods: :view_img_url)
これでJSONにview_img_urlが含まれるようになりました。

2015年6月1日月曜日

postgresqlでadd_columnのafterが効かない

herokuにrailsアプリを載せるために開発していたのですが、
カラムを追加したいとなり、どうせならきれいな位置に配置したいなと思い、
afterを使ってカラムの位置を指定してみたところ、
指定した位置に追加されなかったので調べたときの件です。

こういうテーブルをもともと用意していました。
class CreateItems < ActiveRecord::Migration
  def change
    create_table :items do |t|
      t.string :name
      t.string :img
      t.integer :price
 
      t.timestamps null: false
    end
  end
end

カラムを追加するために以下のコードを追加しました。
class AddColumnToItem < ActiveRecord::Migration
  def change
    add_column :items, :stock, :integer, after: :price
  end
end

追加後にpostgresqlのテーブル定義を確認したところ、
stockがpriceの後ろではなく、テーブルの一番最後のカラムに追加されてしまいました。
$ psql test
psql (9.4.1)
Type "help" for help.
 
test=# \d items
                                     Table "public.items"
   Column   |            Type             |                     Modifiers                      
------------+-----------------------------+----------------------------------------------------
 id         | integer                     | not null default nextval('items_id_seq'::regclass)
 name       | character varying           | 
 img        | character varying           | 
 price      | integer                     | 
 created_at | timestamp without time zone | not null
 updated_at | timestamp without time zone | not null
 stock      | integer                     | 
Indexes:
    "items_pkey" PRIMARY KEY, btree (id)


調べてみたところ、
postgresqlではそもそも列の位置を変えることができないようです。
列の位置を変えたい場合はテーブル作り直すか、
最終的なレイアウトになるまでデータを移す作業をしていくしかないようです。
これに関してはMySQLの方が柔軟でよいですね。
結局、まだ開発中のものだったので、初めからstockをpriceの後に入れたものでテーブルを作り直しました。


http://qiita.com/masamitsu-konya/items/c4f75fc02347de9f8b0f
http://stackoverflow.com/questions/27214251/postgresql-add-column-after-option-usage-in-rails-migration
http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_column#637-Options
http://dba.stackexchange.com/questions/3276/how-can-i-specify-the-position-for-a-new-column-in-postgresql
https://wiki.postgresql.org/wiki/Alter_column_position/ja

2015年5月26日火曜日

Testing Casual Talks #2に参加してきました

Testing Casual Talks #2に参加してきました。
https://atnd.org/events/66159

他の会社やプロジェクトがどういう風にテストやってるのかすごく気になっていたので聞いてきました。
ユニットテストやServerspecでのインフラのテストだけでなく、
E2Eだったり、ミドルウエアの設定についてのテストや、
脆弱性テストまで行うようになっていたりしていて、
どんどんテストが自動化されていっているのだなぁと感じました。
OWASP ZAPやvaddyは試してみたいなと思いました。

発表聞きながらつらつらとメモってたことを載せていきます。


・mruby のテスト方法についての試行錯誤
@hsbtさん
GMOペパボ
http://www.slideshare.net/hsbt/20150525-testing-casualtalks

ミドルウエアに組み込むことができる
ngx_mruby
nginxの中でrubyが動く

nginxだけでも設定できるが、テストができない

Middleware as a Codeといってもいい

モチベーション
productionにngx_mruby使っている
→動いてるコードはテストしたい

ngx_mrubyとして組み込んだ時のnginxの挙動をするダミーをrubyで書いた
ダミーに対して値をセットして、production用コードのテストを行う

rubyのテストはできているけど、mrubyやngx_mrubyのテストはできてないってのがもやもや

mrubyのテストライブラリを探したところ
mruby-mtestがあった。
ngx_mrubyで動かす時にはmruby-mtestは組み込まれない。

今後やりたいこと
mruby-mtestを組み込んだmrubyとngx_mrubyのmrubyは異なるものになるので、そこの差をなくしたい
CIを回したい。環境別のクロスコンパイルをしたい
積極的にテストのあるmrubyのコードにnginx.confを置き換えていきたい


・スクラム開発において、テストメンバー(非開発者)の関わり方を模索してみた
境野高義 (@sakaimo)さん

ガイアックスの伝統サポーターズでの話
https://www.den-suppo.jp/

プロジェクトのチャレンジ
 スクラムのプラクティスを取り入れた開発プロセス(社内で2例目)
QAのチャレンジ
 このプロセスの中にQA(非開発者)が入っていく

狙い1 要件定義の充実
 QAがジョインする
 →仕様の考慮漏れが事前に指摘できた
 →ストーリー間の整合性を事前に取ることができた

狙い2 スプリントごとにテスト
 →スプリント内にテストが収まらなかった

振り返り(KPT)
keep
 要件ヒアリングの際に指摘できる
 まとめてテストよりも細かくテストする方が早く不具合みつけられる
problem
 スプリント内にテストが収まらなかった
 テスト項目の想定が読み切れてなかった
 ストーリー単位ではなく機能単位でのテストになってしまった
try
 テストのやり方、内容を変える
  より異常系をやる
 ストーリーごとにテストする
  フィードバックを早くしていく

まとめ
 スプリントごとにテスト→フィードバックができるのはメリット
 POも交えて軌道修正していける(スクラムのメリット)
 作られたものをテストではなく、一緒にサービスを作っていく感じがよかった


・大規模 Web サービスのブラウザテスト自動化・並列化
@deme0607さん
DeNA

mission
 ゲームプラットフォームの品質保証・向上
 開発生産性の向上

ブラウザ自動テストの構築
 selenium webdriver
 rspec/capybara
 jenkins

自動テスト拡充の利点
効率的なリグレッションテスト
 基本的なテストケースは完全自動化
 リリースサイクルの高速化

 自動テストではカバーできないところに工数を集中させられる
 (UI/レイアウト検証とか)

 問題点
  テスト実行時間の増加

テスト並列化による高速化
 必要なこと
  並列実行しているテストの処理が互いに衝突しないようにする
 アプローチ
  サービス実行環境の独立
  テスト実行ノードごとに専用の環境を用意する
 問題点
  環境構築コストが大きい
  環境依存の問題にテストで気づけない

 テスト専用データの作成
  テストごとに専用のテストデータを作成
  →仕様変更に追従しづらくメンテナンスコスト高い
  →実環境のDBをテストから操作するリスク高い

 テストデータを作成できるAPIを提供
  テストごとにAPIでデータ生成

  問題点
   サービスも同じAPIを利用してデータを作成
   サービスの開発工数かかる

 テスト実行時に作成できないデータは事前に準備
  UI経由でユーザを事前作成
   webdriverで自動化
   UI経由のデータ作成は実行時間がかかる

  事前作成データ利用
   テストの後処理に注意

並列化したテストの運用・改善
 新たに顕在化した問題
  テストが不安定
  テスト失敗に慣れてしまうと、ほんとの不具合に気づかない

 解決策
  地道にテストを修正していく

 テスト結果の集計APIを作成
  失敗しやすいテストの分析を行っている
  突然不安定になったテストケースをslackに通知

 不適切な実行計画
  マシンリソースがあまらないように
  過去のテスト結果の集計結果から、実行計画を作成する

今後の課題
 データ作成APIの充実
 分散実行ノードを動的に増やす仕組み
 並列実行計画の改善


・ECサービスの負荷テストの裏側
@kenchanさん
GMOペパボ
 Gatlingのレポートでは不足していたものの拡充
 データの収集と分析の仕組みづくり

 レポートから見えるもの
  分布を詳しく見たい
   実際のばらつき
   ノイズがないか
  時系列のデータが見たい
   リクエスト開始時と処理時間の相関
   Min,Maxの傾向がないか

 simukation.log(tsv)に生ログあった
  google docsにインポート
  1万行くらいならもっさりするけど行ける


・継続的Webセキュリティテスト
@cakephper / @ichikawayさん
http://www.slideshare.net/ichikaway/web-testing-casual-talks2
webセキュリティテスト
 ホワイトボックス
 ブラックボックス

owasp zap

セキュリティテスト現状の問題点
 リリース直前に大量の脆弱性発見

継続的なセキュリティテストが必要

既存のツールを使う場合
 CIに載せるのが大変

vaddy
 saas型
 CI連携を前提
 テストサーバー必要


・casualにインラフテストへ入門した話
yudoufuさん
https://speakerdeck.com/yudoufu/casualniinhuratesutoheru-men-sitahua

テスト導入以前
 すべてchef
 →チェック作業が手作業でつらい

手元でテストしよう
 test-kitchen
 serverspec

テスト環境構築
 両方chefに含まれてる

実行
 .kitchen.ymlを環境にあわせる

自動テスト化して得たもの
 確認作業が軽減された
 グリーン気持ちいい

その後
 面倒な設定変更が舞い込む
  複雑な設定は動作確認が増える
  →振る舞いテストやる

infrataster
基本サーバーの外部から使うツールだがtest-kitchen使う方法がissueにあった

振る舞いテストによってえたもの
 挙動のテストが書ける
 デグレを未然に防ぎやすくなった
 グリーンがさらに気持ちよくなった


・カジュアルなテスト&仕様書としてJSON+node requestのご提案
kawamoto.minoruさん
@k12uさん
https://speakerdeck.com/k12u/kaziyuarunatesuto-and-shi-yang-shu-tosite-json-plus-node-requestfalsegoti-an

面倒でもやらなきゃいけない仕事
 仕様書
 フロントエンドとの連携(外部仕様作りながらAPI開発)

JSON APIの応答をチェックする
仕様もJSONで書く
requestとresponseのjsonを用意

タイトルの元ネタ
WebAPIリクエスト仕様書としてcurlコマンドのご提案
http://qiita.com/Hiraku/items/dfda2f8a5353b0742271

2015年5月14日木曜日

JAWS-UG初心者支部【第1回】に参加してきました

JAWS-UG初心者支部【第1回】に参加してきました。
https://jawsug-beginner.doorkeeper.jp/events/22161

AWSの勉強会を探してみてて、できればレベル低めのがいいなと思ってたところ、
今回の勉強会をdoorkeeperで見つけました。
登録したときはキャンセル待ち50人以上だったけど、無事に参加できました。
隣の人と3分間ずつ話すという出会い系ワークショップがあったりしておもしろかったですw
そしてAWSは目的を決めて、あとは自分でやってみてナンボだなと改めて思いました。

今回メモったことをつらつらと載せていきます。


■オープニング+JAWS-UGの紹介 :青木 由佳 さん(株式会社パソナテック)@yuka_jyotei
・JAWS-UG = Japan AWS User Group
読み方はじょーずゆーじー

・AWS関連のイベントいっぱいある
JAWS DAYS https://jaws-days.doorkeeper.jp/
JAWS Festa
AWS Summit Tokyo 2015
re:Invent @ラスベガス

■「社内情シス インフラ運用担当のAWS初心者がJAWS-UG初心者支部で言いたい10のこと(仮)」:伊藤勇気さん(本田技研工業株式会社)@mogutan1978
・初心者がどう思ってるか話してってことで登壇
1.主催者のみなさまありがとう
2.自己紹介
3.今はAWS抜きにはクラウド語れないよねぇ、以外語れない
4.オンプレ依存症が完治していない
5.OSS/各種サービス利用に抵抗を持っていたりする(優しい顔して近づいてくるw)
6.社内IT運用に辟易している
7.でも変えてやりたいと思っている
8.じゃあ何したいわけ → VPCをしっかり勉強することがいいのではと考えている
9と10.なかった

■インフラに苦手意識を持つ女子新入社員がAWSに触れてちょっとありかなと思った話(仮):橋本さん(株式会社内田洋行)
社会人歴:1年1ヶ月
AWS歴:半年

・インフラに配属
インフラのイメージ
 広い知識がないとやっていけなそう
 アプリより地味
 絶対一度は作業中にサーバー壊す

・仕事とAWS
担当クラウドサービスのインフラをAWSに移行

・半年間のAWS勉強内容
とにかくやってみる
気が済むまでやってみる

参考書1冊やってみた
 さわって学ぶクラウドインフラ Amazon Web Services基礎からのネットワーク&サーバー構築
 http://www.amazon.co.jp/dp/4822262960
ネットで公式や先人の知恵を活用する
 クラスメソッド社のブログで内容・手順確認
 自分のAWS環境で実際に検証
 さらに必要であれば公式で確認

・心境の変化
敷居高くない
サーバーだけじゃなくやることたくさんあってむしろ熱い
サーバー使い捨てできて失敗がいくらでもできる環境ってありがたい
椅子に座ってるだけで仕事できる(DCとか行かない的な意味)

■AWS初心者に贈る〜AWS関連コンテンツを使い倒そう〜:ただあゆみさん (くまモン好き) @applebear_ayu
・AWS Samurai 2014受賞

・好きなAWSサービス
EC2(HPCインスタンス) IAM,AWS Config
AWSの勉強会では自分の好きなAWSサービスを言うのが定番らしい

・新しいことを勉強する上で大切な2つのこと
何のために勉強するのか?本質目標は?
 「AWSを勉強すること」だと行き詰まってしまう
机上で何かをするのではなく、とにかく飛び込む
 現場、現物、現実が大事

・初心者が抑えたいAWSコンテンツ
無料枠の活用
→とにかく自分の手を動かして経験を積む
 1年間の無料枠を有効に使おう
 新しいアカウント作っても古いやつと一括請求すると無料枠剥奪されるので注意
 $25の無料利用クーポンが今ならゲットできる
 http://aws.amazon.com/jp/campaigns/2015console/

セルフペースラボ
 AWSをオンデマンドで実践的に学習できるサービス

AWSの公式Webiner(オンラインセミナー)
 初心者向けオンラインセミナー
  非エンジニアにもおすすめ
 Black Belt Tech Webiner(旧マイスターシリーズ)
  経験者・エンジニア向け
  過去資料もたくさんあるが、サービスの変化が激しいので可能な限り新しいのを探した方が良い

・書籍を活用しよう
Amazonのクラウドエンジニアが選ぶ技術書35選
http://www.amazon.co.jp/b?node=3517238051

・Blogなど優良なサイトの情報を活用しましょう
Google先生に尋ねるときに足したいキーワード
 AWS blog(またはAWS ブログ)
  AWSの公式ブログ

 AWS blog SA
  AWS Solution Architectブログ
  AWS パートナーSAブログ
  日本オリジナルの記事が数多くある

 Developers.IO(または classmethod)
  クラスメソッドのブログ

・Qiitaを活用しよう
AWSの場合はサービス名でしかタグをつけていない人もいるので要注意

・資料共有サイトを活用しよう
slideshareとかspeakerdock

・SNSを活用しよう
AWS界隈の人は有用な情報をハッシュタグ #jawsugをつけてよくつぶやく

今すぐフォローすべきAWS界隈の素晴らしきエンジニア達【2014年版】
http://dev.classmethod.jp/cloud/aws/lets-follow-aws-engineers-now-2014/

・JAWSの他支部の勉強会に参加しよう
全国で50くらいある

■re:Inventへ行こう! :榎本さん(株式会社エイチ・アイ・エス)
・re:Inventってなに?
世界最大のAWSグローバルカンファレンス
 キーノート
 技術セッション
 ワークショップ

・技術の勉強だけで行くともったいない
スライドや動画はすぐ公開される
センセーショナルな発表は日本メディアでの扱いも大きい
情報のキャッチアップはこれだけで十分

・技術の勉強以外の目的
人との出会い
会場の熱気や雰囲気を感じる

・出会いのキッカケ
会場にいる人はAWSに興味しんしんで、全員仲間ですよ
ツアー参加するとキッカケが多くなる
ぶっちゃけ喫煙者の方が有利

・出会いのキッカケの後
AWSという共通の話題がある
SNSでつながりを作る
仲間になる
re:InventもJAWS-UGも同じ

・re:Inventの2つの参加方法
ツアーで行く
個人で行く

・FAQ
稟議が取れません
→上司説得テンプレートがあります
http://yoshidashingo.hatenablog.com/entry/2014/09/01/191310

嫁の許可が取れません
→一緒に行けばいいじゃん
 セッション中はシルク・ドゥ・ソレイユやブルーマンとか見ていてもらう

■AWS書籍活用術(仮) :佐々木さん(NRIネットコム)
http://www.slideshare.net/takurosasaki/jawsug-beginnersbook

AWS歴9年
ブログ : http://blog.takuros.net/

・媒体としての書籍の特徴
AWS本各種
 テーマ・読者層を設定し、網羅率が高い
 最初から読むと、ひと通り通りでマスターできるはず
雑誌 WEB+DB PRESSとか
 特定のテーマに特化して、高度な内容も多い
公式サイト
 すべての情報が乗っているが、検索しずらい
Developers.IO
 AWSでググると必ず引っかかる

・AWS本の定番3冊 日経BP社
クラウドデザインパターン 設計ガイド
http://www.amazon.co.jp/dp/4822211967
 クラウド・ネィティブな設計をする際におすすめ
 改訂版がもうすぐ出るので今すぐ買わないほうがよい
クラウドデザインパターン 実装ガイド
http://www.amazon.co.jp/dp/4822211983
 画面キャプチャ付きの操作ガイドもある
基礎からのネットワーク&サーバー構築
http://www.amazon.co.jp/dp/4822262960
 AWSを使ってネットワーク&サーバー構築の勉強
 AWS全体を学ぶには不向き

・情シス向けの2冊
Amazon Web Services入門 企業システムへの導入障壁を徹底解消
http://www.amazon.co.jp/dp/4844336479
 導入時に突っ込まれやすい内容についての解説
情シス・マネジャーのための早わかりAWS入門
http://www.amazon.co.jp/dp/4822275337
 そのままズバリのタイトル

・概要を理解するのに最適な1冊
Amazon Web Services 徹底活用ガイド(日経BPムック)
http://www.amazon.co.jp/dp/482226999X
 AWSの概要説明と導入企業の事例紹介

・一番分厚いAWS本
Amazon Web Services パターン別構築・運用ガイド(著書)
http://www.amazon.co.jp/dp/4797382570

ある程度AWSを理解した上で、
もう一歩レベルが上げられるような内容を目指しています

AWS初心者にAutoScalingについてヒアリングすると
9割 聞いたことがある
8割 使えるようになりたい
1割 使ったことがある
なりたいからあるへのギャップが大きい


・技術書の読み方(自己流)
目標設定が命
 失敗 「AWSを使えるようになりたい」
 →ゴールが不明確で、何を持って目標達成か測定不能
 成功 「負荷に応じて、自動でサーバーが増減するシステムを作りたい」
 →ゴールが明確で達成度がわかりやすい

読み方
 目次を読む
 15-30分くらいかけて、ぱらぱらとめくる
 必要そうなところだけ読む
 手を動かして、実際に試す
 全部読まない

・余談
書籍について
→1ページ書くのに3-4時間

AWS本が少ない理由
→ユーザーが少ない
→書いているうちに内容が変わっていくので大変

執筆すると儲かる?
→割にあわない

本を出版するには?
→ブログ書いてたら出版社から声かかった

amazonレビュー
→書いてください

書評ブログ
→書いてくれたら嬉しい

書いている間にもAWSがどんどん進化する
→本の増刷が決まったが、マネジメントコンソールが日本語化されたのでキャプチャ取り直してるそうです


■「セルフペースラボで気軽に始めるAWS」 :にへいさちこさん(あそびにん)
あそびにん=特定の職業についていない

・今回の補足資料
http://bit.ly/1Ef7p01

・セルフペースラボ
https://run.qwiklab.com/?locale=ja
演習問題+演習環境のセットを時間で利用可能
リソース消し忘れの心配不要
16個の無料ラボあり
無料ラボだけならクレカ不要
無料ラボは利用可能時間が短めなので、手順をしっかり読んでから開始したほうがよい


2015年5月9日土曜日

macにhomebrewでpython入れようとしたらエラー出たときの対応

macにhomebrewでpython入れようとしたらエラー出たので、そのときの対応です。

$ brew install python
==> Downloading http://www.python.org/ftp/python/2.7.7/Python-2.7.7.tgz
Already downloaded: /Library/Caches/Homebrew/python-2.7.7.tgz
==> ./configure --prefix=/usr/local/Cellar/python/2.7.7_1 --enable-ipv6 --datarootdir=/usr/local/Cellar/python/2.7.7_1/share --
==> make
==> make install PYTHONAPPSDIR=/usr/local/Cellar/python/2.7.7_1
==> make frameworkinstallextras PYTHONAPPSDIR=/usr/local/Cellar/python/2.7.7_1/share/python
==> Downloading https://pypi.python.org/packages/source/s/setuptools/setuptools-4.0.1.tar.gz
Already downloaded: /Library/Caches/Homebrew/python--setuptools-4.0.1.tar.gz
Error: SHA1 mismatch
Expected: a43549f4a01f314bf54567628f8de7d1c03d5930
Actual: 6d417376509eee44c1da34692fb5d805fd2915c6
Archive: /Library/Caches/Homebrew/python--setuptools-4.0.1.tar.gz
To retry an incomplete download, remove the file above.

SHA-1 mismatchということなので、Archiveのファイルが古いようです。
homebrewのupdateをしてみました。

$ brew update
==> Updated Formulae
python

homebrewをupdateした後だと、無事にインストールできました。
$ brew install python
==> Installing dependencies for python: readline, sqlite, openssl
==> Installing python dependency: readline
==> Downloading https://homebrew.bintray.com/bottles/readline-6.3.8.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring readline-6.3.8.yosemite.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local.

Mac OS X provides similar software, and installing this software in
parallel can cause all kinds of trouble.

OS X provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/readline/lib
    CPPFLAGS: -I/usr/local/opt/readline/include

==> Summary
🍺  /usr/local/Cellar/readline/6.3.8: 40 files, 2.1M
==> Installing python dependency: sqlite
==> Downloading https://homebrew.bintray.com/bottles/sqlite-3.8.9.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring sqlite-3.8.9.yosemite.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local.

Mac OS X already provides this software and installing another version in
parallel can cause all kinds of trouble.

OS X provides an older sqlite3.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/sqlite/lib
    CPPFLAGS: -I/usr/local/opt/sqlite/include

==> Summary
🍺  /usr/local/Cellar/sqlite/3.8.9: 9 files, 2.2M
==> Installing python dependency: openssl
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2a-1.yosemite.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring openssl-1.0.2a-1.yosemite.bottle.1.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl/certs

and run
  /usr/local/opt/openssl/bin/c_rehash

This formula is keg-only, which means it was not symlinked into /usr/local.

Mac OS X already provides this software and installing another version in
parallel can cause all kinds of trouble.

Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/openssl/lib
    CPPFLAGS: -I/usr/local/opt/openssl/include

==> Summary
🍺  /usr/local/Cellar/openssl/1.0.2a-1: 463 files, 18M
==> Installing python
==> Downloading https://homebrew.bintray.com/bottles/python-2.7.9.yosemite.bottle.13.tar.gz
######################################################################## 100.0%
==> Pouring python-2.7.9.yosemite.bottle.13.tar.gz
==> Caveats
Pip and setuptools have been installed. To update them
  pip install --upgrade pip setuptools

You can install Python packages with
  pip install 

They will install into the site-package directory
  /usr/local/lib/python2.7/site-packages

See: https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/Homebrew-and-Python.md

.app bundles were installed.
Run `brew linkapps python` to symlink these to /Applications.
==> /usr/local/Cellar/python/2.7.9/bin/python -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/
==> /usr/local/Cellar/python/2.7.9/bin/python -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/
==> Summary
🍺  /usr/local/Cellar/python/2.7.9: 4808 files, 77M

2015年4月29日水曜日

railsでlink_toにmethod: :delete指定した時に動かなくてrails.js探した

railsでlink_toにmethod: :delete指定したら、
DELETEメソッドで飛んでくるはずがGETメソッドで飛んできて想定どおりに動きませんでした。

調べたところrails.jsが必要というのが見つかったので、
rails.jsってどこにあるんだと調べてみたところ、
jquery-railsの中にあるjquery_ujs.jsを読み込めばいいことがわかりました。

application.jsに以下を追加で解決しました。
//= require jquery_ujs


参考URL
http://d.hatena.ne.jp/spitfire_tree/20120323/1332477590
http://techracho.bpsinc.jp/kazumasa-ogawa/2011_12_27/4874
https://github.com/rails/jquery-ujs

2015年4月25日土曜日

React.js meetup #1に参加してきました

今日はReact.js meetup #1に参加してきました。
http://reactjs-meetup.connpass.com/event/11232/
一人当たりの持ち時間が短くてバタバタしてる感じでしたが、
とても有意義な話が聞けてすごく刺激を受けて帰ってきました。
メモったことや感想をつらつらと載せていきます。


・React 概論 @naoya_itoさん
https://speakerdeck.com/naoya/reactgai-lun
今日発売のWEB+DB PRESSにreact.jsの記事書いたそうです。

PHPフレームワークのXHPの移植として開発されたのがきっかけ
facebookのプロダクションで絶賛使われてるってのがいい

≒サーバーサイド脳で書ける
Viewは常に全更新
Viewは宣言的に定義

従来の手法の難しさ=DOM操作の難しさ
-DOMが状態を持っている
-グローバル (どこからでも書き換えられる)
-非同期 (外部と通信したりとか)

VirtualDOM
-速度チューニングする余地は残されている
-通常使う時はVirtualDOM気にすることはない

Reactの責務
1 DOMの更新
2 イベントへの反応

サーバーサイド脳でいける
コンポーネント指向(変更がコンポーネントに局所化される)
データフローが明確

生産性より信頼性
-可読性、保守性など長期的な信頼性に重きを置いている
-書く時間より読む時間の方が長いよね

jquery併用できる
-DOM操作はパラダイムが違うのでよくわかんないでやるべきではない
-$ajaxとかは使ってかまわない


・react-rails @hokacchaさん
https://speakerdeck.com/hokaccha/react-rails-1
react-railsはreactjsの公式が作っているgem

mount view helper and UJS
-マウントするコードを書かなくていい
-APIリクエストしない分高速

server side Rendering
-{ prerender: true }をつける
どうやってやっているか
--ExecJSでJSを実行
--therubyracer(V8)推奨

ベンチマーク
-react > haml
-hamlと同等かそれより早いくらい
-死ぬほど遅いわけではなさそうというのがわかるベンチマーク

turbolinks
-普段はまっさきにOFFにするけど、使っても動く

まとめ
-グリングリン動くSPAとかにはたぶん向かない
-部分的に動的コンテンツがあるようなアプリケーションだと使いどころあるかも
-Turbolinksにわんちゃんあるかも


・10分で実装するflux @azuさん
http://azu.github.io/slide/react-meetup/flux.html
#データフローを追っかけていったので、フローがわかりやすかったですが、
#話は難しかったです。。


・mercury/mithril.js @yosuke_furukawaさん
https://speakerdeck.com/yosuke_furukawa/mithril-dot-js
introduction to react=神資料
https://speakerdeck.com/hokaccha/introduction-to-react

react
-shouldComponentUpdate
-子ノードのすべてを再描画しないようにさせる

mithrilのアプローチ
-再描画のタイミングを制御して回数を減らす
-イベントの最後に再描画という形にしなくてよくなる

mercuryのアプローチ
-再描画の回数を減らす
-VDOMのtreeの探索範囲を限定する


・React/SPAの設計と運用 @mizchiさん
https://gist.github.com/mizchi/ee8256f7783dde2bea8d
#実際に開発していってぶちあたった壁とどう乗り越えたかのお話でした


・LT - React.jsと、Railsとかアイドルとか @sugyanさん
http://sugyan.com/presentations/reactjs-meetup-1/#/
@hokacchaさんの話でも出てきたturbolinksではまったのでOFFにしたそうです


・LT - Java+React.jsでServer Side Rendering @makingさん
http://www.slideshare.net/makingx/reactjs-meetupjavassr
javaでも標準でjsのengine使えるよ


・LT - React.js(React Native) + UI Design Prototyping @tsuyoshi higuchiさん
https://speakerdeck.com/tyshgc/rapid-react-prototyping-react-dot-jsdeuidezainpurototaipuwozuo-ru
デザイナーがコンポーネントを意識してデザインを作る
Photoshopのcomponent情報からreactのjsx吐き出すツール作ってた。
#すごい

2015年4月24日金曜日

mixi iOS Training 第8回に参加してきました

mixi iOS Training 第8回に参加してきました。
http://app-training.connpass.com/event/14125/
だいぶ会場に来る人は減ってきた感じがしますが、
その分質問とかしやすそうな雰囲気です、したことないですがw

今回も前回に引き続き、TODOアプリの開発です。
今回はTODOの削除と永続化について学びました。

TODOを削除する
https://github.com/mixi-inc/iOSTraining-TODO-App/issues/3

TODOの永続化
https://github.com/mixi-inc/iOSTraining-TODO-App/issues/4

教材
https://github.com/mixi-inc/iOSTraining-TODO-App

また授業の中でメモったことをつらつらと載せていきます。

・#pragma mark HOGEHOGE
ソースの上にあるパンくずリストにHOGEHOGEが追加されて、選択するとそこに遷移できる

・// TODO: HOGEHOGE
同じくパンくずリストにTODOが追加される(FIXMEでも出る)

・NSArrayをNSMutableArrayに変換するやりかたはいくつかある
NSMutableArray *arr = @[].mutableCopy;
[NSMutableArray arrayWithArray:@[]];

・buildできなくてはまるよくあるパターン
Target Membershipのチェック外れてる

・クラッシュしたときの話
スタックトレースよりもその上のエラーメッセージを読んで解決することが多い

・アプリの状態
Inactive
→アプリを起動してて一番上にいるけど、通知センターを開いている状態
Suspended
→OSがプロセスをkillした

・シミュレータでのHOMEボタンのショートカット
command + shift + h

・plistにセキュリティ的によくないものは保存しない
講師の方曰く、このくらい危険らしいw
→UserDefaultsにパスワードを保存しないでください = あなたのamazonのパスワードを手のひらに書かないでください

・ObjectiveCでnilに対してメソッドを実行しても何も起きない(エラーにならない)
javaだとヌルポで落ちるよね


次回はちょっと空いて5/21だそうです。

2015年4月20日月曜日

capybaraでidもlabelもないラジオボタンを選択する

またcapybaraのテストを書いていて、 idもlabelも使ってないラジオボタンを選択する方法を調べました。 自分の場合はこのやり方で選択できました。
  • 銀行振込
  • 代金引換便
  • クレジットカード決済
  • その他
  • s.find(:xpath, ".//input[@value='2']/..").choose 'deal_type'

    2015年4月15日水曜日

    SmartNews TechNight Vol.2に参加してきました

    SmartNews TechNight Vol.2に参加してきました。
    https://atnd.org/events/64096

    ハッシュタグはこちら
    https://twitter.com/hashtag/smarttechnight

    聞いてて思ったのは、
    大きなサービスもってる大きな会社は大量発注で安くサーバー仕入れるので、
    コストという観点からいくとオンプレの方が有利なんだなと。
    ただ、どこも便利なものは使っていこうという姿勢だったのでいいですね。

    トークセッションはちょっとメモれなかったですが、
    その他のプレゼン聞いててメモったことをつらつらと書いていきます。

    SmartNews大平さん
    ・SmartNewsにはインフラ専任がいない
    ・すべてAWSに乗っている
    http://aws.amazon.com/jp/solutions/case-studies/smartnews/
    ・使ってるSaas
      Datadog
      NewRelic
      pagerduty
      logentries
      chartio
    ・クラウド使うと得意領域は違ってもアプリエンジニアとインフラエンジニアでやることはだいたい同じになってくる

    GREE梶原さん
    ・最近の新規のサービスはAWSで取り組んでる
    ・クラウドかオンプレかの選定基準(現時点)
      コスト
       大規模調達するとまだまだ物理サーバーが安い
       年に数回AWSの値下げが実施されるのでもっと安くなってほしい
      メンテナンスの自由度
       サービスによってメンテナンスの調整コストが高いものがある
    ・使ってるSass
      PagerDuty
      SumoLogic
      DataDog

    CyberAgent桑野さん
    ・クラウドの時代になってもやることは変わらないけど、やり方が変わってきている
      コード化するためのツールのコモディティ化
      そもそも1から自分で構築しない
      基本的な部品のAPI化
      スピード感がましている/キャッチアップが大変
    ・いろんな職種のエンジニアがいるのではなくて、得意な技術領域の異なるエンジニアがいるだけ

    2015年4月14日火曜日

    capybaraのテストでセットされたcookieを取得する

    capybaraでテストを書いていて、独自にセットしたcookieが
    ちゃんとセットされたかをテストしたかったのでcookieの取得方法を調べました。

    cookieはこれで取れるようです。
    Capybara.current_session.driver.request.cookies.[]('cookie名')

    こんな感じのテストコードを書きました。
    it 'ログイン' do
      visit '/login'
      fill_in 'email', with: 'aaa@bbb.com.ne'
      fill_in 'password', with: '1234567890'
      click_on 'Login'
     
      expect(page.driver.status_code).to eq(200)
      expect(Capybara.current_session.driver.request.cookies.[]('login_token')).not_to eq(nil)
     
      # 確認用
      # puts Capybara.current_session.driver.request.cookies.[]('login_token')
    end
    


    参考URL
    http://stackoverflow.com/questions/19325960/rails-cucumber-capybara-how-to-set-retrieve-cookies-in-tests

    2015年4月10日金曜日

    mixi iOS Training 第7回に参加してきました

    またmixiのiOS Trainingに参加してきました。
    http://app-training.connpass.com/event/13617/
    今回はTODOアプリの2回目で、新しいTODOを追加できるようにしました。

    コードはこちら
    https://github.com/mixi-inc/iOSTraining-TODO-App
    やることはこちら
    https://github.com/mixi-inc/iOSTraining-TODO-App/issues/2
    今回のスタートはshow-todoブランチで、今回のゴールはadd-todoブランチ。

    講義の最初は最近恒例のまずgitの使い方から。
    この中でやってたターミナルからFinder開く方法
    open .
    これ初めて知りました。

    講義を受けながらつらつらとメモったことを載せていきます。
    ・NavigationController の rootViewControllerはデフォルトで表示するもの

    ・XCodeのSource Controllからgitのcommitもできる
    対象ファイルとdiffが見やすくなっているので便利

    ・Bar Button ItemはNavigationController管理下じゃないと置けない

    ・メソッドをこう定義した場合
    - (void)doneButtonTapped:(id)sender{
    NSLog(@"doneButtonTapped");
    }
    「doneButtonTapped:」の:までがメソッド名。

    ・storyboardを開いてDebug View Hierarchyで3Dに表示できる。



    前回と違って今回は落ちこぼれなかったので、すごく有意義な時間が過ごせました。
    ここでしか触ってないけどさすがに7回もやってると少しずつ慣れてきてるのかなぁと思ったりしてます。
    中級者くらいまではなりたいなと思う今日この頃です。

    2015年3月31日火曜日

    mixi iOS Training 第6回に参加してきました

    先週の話ですが、mixiのiOS Training 第6回に参加してきました。
    これまでとは形式が変わって、TODOアプリを作りながら必要なものを学んでいく形になりました。
    http://app-training.connpass.com/event/13059/

    教材はこれで、
    https://github.com/mixi-inc/iOSTraining-TODO-App
    テキストはこれでした。
    uitableview

    今回はTODOリストを一覧表示するだけの機能だったのですが、
    最初の課題のところではまってしまい、あまりメモが取れませんでした。
    原因は結局コピペしたところが間違ってたわけですが、
    言語の理解が浅いから気づかないのでだめなんだなと反省しています。。。


    そんな中メモった内容を載せておきます。
    ・ショートカット
    行を選択してCommand + / でコメントアウト
    ・pixel指定の話
    pixelが少数になった場合は切り捨てられる
    ・UITableViewのSeparatorは1pxですよ
    ここに詳しく載ってます
    http://335g.hatenablog.jp/entry/2013/12/25/135219

    2015年3月23日月曜日

    macにwiresharkをhomebrewで入れる

    homebrew便利です。wiresharkも簡単に入れられました。
    MacのバージョンはMavericksです。

    $ brew install wireshark --with-qt
    ==> Installing dependencies for wireshark: gettext, libffi, glib, libtasn1, gmp, nettle, gnutls, libgpg-error, libgcrypt, d-bus, geoip, c-ares, qt
    ==> Installing wireshark dependency: gettext
    ==> Downloading https://homebrew.bintray.com/bottles/gettext-0.19.4.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring gettext-0.19.4.mavericks.bottle.tar.gz
    ==> Caveats
    This formula is keg-only, which means it was not symlinked into /usr/local.
     
    Mac OS X provides similar software, and installing this software in
    parallel can cause all kinds of trouble.
     
    OS X provides the BSD gettext library and some software gets confused if both are in the library path.
     
    Generally there are no consequences of this for you. If you build your
    own software and it requires this formula, you'll need to add to your
    build variables:
     
        LDFLAGS:  -L/usr/local/opt/gettext/lib
        CPPFLAGS: -I/usr/local/opt/gettext/include
     
    ==> Summary
    🍺  /usr/local/Cellar/gettext/0.19.4: 1920 files,  21M
    ==> Installing wireshark dependency: libffi
    ==> Downloading https://homebrew.bintray.com/bottles/libffi-3.0.13.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring libffi-3.0.13.mavericks.bottle.tar.gz
    ==> Caveats
    This formula is keg-only, which means it was not symlinked into /usr/local.
     
    Mac OS X already provides this software and installing another version in
    parallel can cause all kinds of trouble.
     
    Some formulae require a newer version of libffi.
     
    Generally there are no consequences of this for you. If you build your
    own software and it requires this formula, you'll need to add to your
    build variables:
     
        LDFLAGS:  -L/usr/local/opt/libffi/lib
     
    ==> Summary
    🍺  /usr/local/Cellar/libffi/3.0.13: 13 files, 388K
    ==> Installing wireshark dependency: glib
    ==> Downloading https://homebrew.bintray.com/bottles/glib-2.42.2.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring glib-2.42.2.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/glib/2.42.2: 410 files,  17M
    ==> Installing wireshark dependency: libtasn1
    ==> Downloading https://homebrew.bintray.com/bottles/libtasn1-4.2.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring libtasn1-4.2.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/libtasn1/4.2: 55 files, 568K
    ==> Installing wireshark dependency: gmp
    ==> Downloading https://homebrew.bintray.com/bottles/gmp-6.0.0a.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring gmp-6.0.0a.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/gmp/6.0.0a: 15 files, 3.2M
    ==> Installing wireshark dependency: nettle
    ==> Downloading https://homebrew.bintray.com/bottles/nettle-2.7.1.mavericks.bottle.1.tar.gz
    ######################################################################## 100.0%
    ==> Pouring nettle-2.7.1.mavericks.bottle.1.tar.gz
    🍺  /usr/local/Cellar/nettle/2.7.1: 66 files, 1.7M
    ==> Installing wireshark dependency: gnutls
    ==> Downloading https://homebrew.bintray.com/bottles/gnutls-3.3.13.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring gnutls-3.3.13.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/gnutls/3.3.13: 1020 files, 8.8M
    ==> Installing wireshark dependency: libgpg-error
    ==> Downloading https://homebrew.bintray.com/bottles/libgpg-error-1.18.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring libgpg-error-1.18.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/libgpg-error/1.18: 17 files, 332K
    ==> Installing wireshark dependency: libgcrypt
    ==> Downloading https://homebrew.bintray.com/bottles/libgcrypt-1.6.3.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring libgcrypt-1.6.3.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/libgcrypt/1.6.3: 16 files, 1.3M
    ==> Installing wireshark dependency: d-bus
    ==> Downloading https://homebrew.bintray.com/bottles/d-bus-1.8.14.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring d-bus-1.8.14.mavericks.bottle.tar.gz
    ==> Caveats
    To have launchd start d-bus at login:
        ln -sfv /usr/local/opt/d-bus/*.plist ~/Library/LaunchAgents
    Then to load d-bus now:
        launchctl load ~/Library/LaunchAgents/org.freedesktop.dbus-session.plist
    ==> /usr/local/Cellar/d-bus/1.8.14/bin/dbus-uuidgen --ensure=/usr/local/var/lib/dbus/machine-id
    ==> Summary
    🍺  /usr/local/Cellar/d-bus/1.8.14: 39 files, 2.0M
    ==> Installing wireshark dependency: geoip
    ==> Downloading https://homebrew.bintray.com/bottles/geoip-1.6.5.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring geoip-1.6.5.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/geoip/1.6.5: 16 files, 736K
    ==> Installing wireshark dependency: c-ares
    ==> Downloading https://homebrew.bintray.com/bottles/c-ares-1.10.0.mavericks.bottle.tar.gz
    ######################################################################## 100.0%
    ==> Pouring c-ares-1.10.0.mavericks.bottle.tar.gz
    🍺  /usr/local/Cellar/c-ares/1.10.0: 57 files, 540K
    ==> Installing wireshark dependency: qt
    ==> Downloading https://homebrew.bintray.com/bottles/qt-4.8.6.mavericks.bottle.6.tar.gz
    ######################################################################## 100.0%
    ==> Pouring qt-4.8.6.mavericks.bottle.6.tar.gz
    ==> Caveats
    We agreed to the Qt opensource license for you.
    If this is unacceptable you should uninstall.
     
    .app bundles were installed.
    Run `brew linkapps qt` to symlink these to /Applications.
    ==> Summary
    🍺  /usr/local/Cellar/qt/4.8.6: 2790 files, 122M
    ==> Installing wireshark
    ==> Downloading https://www.wireshark.org/download/src/all-versions/wireshark-1.12.4.tar.bz2
    ######################################################################## 100.0%
    ==> Patching
    patching file configure
    Hunk #1 succeeded at 16946 (offset 243 lines).
    ==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/wireshark/1.12.4 --with-gnutls --disable-gtktest --with-qt
    ==> make
    ==> make install
    ==> Caveats
    If your list of available capture interfaces is empty
    (default OS X behavior), try the following commands:
     
      curl https://bugs.wireshark.org/bugzilla/attachment.cgi?id=3373 -o ChmodBPF.tar.gz
      tar zxvf ChmodBPF.tar.gz
      open ChmodBPF/Install\ ChmodBPF.app
     
    This adds a launch daemon that changes the permissions of your BPF
    devices so that all users in the 'admin' group - all users with
    'Allow user to administer this computer' turned on - have both read
    and write access to those devices.
     
    See bug report:
      https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3760
    ==> Summary
    🍺  /usr/local/Cellar/wireshark/1.12.4: 270 files,  64M, built in 3.8 minutes
    

    wiresharkの起動は以下のコマンドでやります。
    $ wireshark-qt
    

    参考URL
    http://momijiame.tumblr.com/post/43785788212/mac-os-x-mountain-lion-homebrew-wireshark
    http://stackoverflow.com/questions/26242156/install-wireshark-on-macos-x-via-brew

    2015年3月18日水曜日

    gitでリモートブランチを削除する

    gitのリモートブランチを消すことがあるのですが、
    やろうとするといつもやり方忘れて調べてるのでここにメモ。

    まずはローカルのブランチの削除
    $ git branch -d test
    Deleted branch test (was 927001f).
    

    ローカルのブランチ削除でエラー出るときは強制的に削除
    $ git branch -d test
    error: The branch 'test' is not fully merged.
    If you are sure you want to delete it, run 'git branch -D test'.
     
    $ git branch -D test
    Deleted branch test (was 5c0b0be).
    

    続いてリモートブランチの削除。
    調べてみたらいくつかやり方があるみたいです。
    $ git push origin :test
    To git@github.com:syakasyaka/sample.git
     - [deleted]         test
    

    git1.7.0以降からはこちらも使える。
    $ git push --delete origin test
    To git@github.com:syakasyaka/sample.git
     - [deleted]         test
    
    直感的には後者のやつの方がわかりやすいですね。


    参考URL
    http://shoma2da.hatenablog.com/entry/2014/03/08/234523
    http://blog.koogawa.com/entry/2014/03/08/121751
    http://www.backlog.jp/git-guide/reference/remote.html
    http://hail2u.net/blog/software/git-push-delete.html

    2015年3月13日金曜日

    mixi iOS Training第5回に参加してきました

    またmixiで開催されたiOS Trainingの勉強会に行ってきました。
    http://app-training.connpass.com/event/12473/

    最初のゲストインタビューはトレタの@y_kohさんで、
    トレタのサービス紹介と開発手法についての発表でした。
    トレタではクラッシュレポートにHockeyAppを使ってるそうです。
    詳しくはここにあるそうです。
    http://qiita.com/y_koh/items/81d8648914a893ec2d16

    授業でメモったことをつらつらと書いていきます。

    3.3 UIView Animation
    https://github.com/mixi-inc/iOSTraining/wiki/3.3-UIView-Animation

    ・アニメーション止めたりとかはbegin/commitで実装

    ・xibはpropertyでIBOutletとして読み込ませる


    Auto Layout入門
    https://github.com/mixi-inc/iOSTraining/wiki/Auto-Layout%E5%85%A5%E9%96%80

    ・missing constraintsは今の状態で位置と高さと幅が決定できるかどうかで出る。
    xcodeが自動で補完する機能あるが、昔は押した結果また出てくるという無限ループに陥ることがあった

    ・auto layoutはシンプルにしたほうがいい
    複雑なものを後から見たりすると死にたくなる


    Auto Layout ドリル
    https://github.com/mixi-inc/iOSTraining/wiki/Auto-Layout-%E3%83%89%E3%83%AA%E3%83%AB

    ・Update Framesで制約に従った場所にviewが移動してくれる
    (ずれてないときは実行できない)

    ・leading edgesとtrailing edges
    文章を書くときに先頭に来る方向がleadingで末尾の方がtrailing
    多言語対応のためにright,leftではないらしい


    次回からはTODOアプリ作りながら学んでく形式。楽しみだ。

    2015年3月9日月曜日

    railsでfind_each使った時にはまった件

    railsでバッチ処理を書いててfind_eachを使おうとしたらエラーではまった時にやったことです。

    まず最初はこんな感じのテーブルにしていました。
    mysql> desc mail_send_targets;
    +-------------+------------+------+-----+---------+-------+
    | Field       | Type       | Null | Key | Default | Extra |
    +-------------+------------+------+-----+---------+-------+
    | user_id     | bigint(20) | NO   | MUL | NULL    |       |
    | item_id     | bigint(20) | NO   | MUL | NULL    |       |
    | expire_date | datetime   | NO   |     | NULL    |       |
    +-------------+------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    

    このテーブルに対して、こういうコードを書いたところ、実行したらエラーがでました。
    targets = MailSendTarget.where(item_id: item_id)
    targets.find_each(batch_size: 2000) do |target|
      #処理
    end
    
    ERROR -- : Mysql2::Error: Unknown column 'mail_send_targets.' in 'order clause': SELECT  `mail_send_targets`.* FROM `mail_send_targets`  WHERE `mail_send_targets`.`item_id` = 96  ORDER BY `tmp_mail_send_targets`.`` ASC LIMIT 2000 (ActiveRecord::StatementInvalid)
    

    エラーの内容を見ていくと、ORDER BYのカラムが指定されていなくて、
    どうやらprimary keyをorder byに指定するようなので、
    テーブルにprimary keyを設定する必要がありそうです。
    mysql> desc mail_send_targets;
    +-------------+------------+------+-----+---------+-------+
    | Field       | Type       | Null | Key | Default | Extra |
    +-------------+------------+------+-----+---------+-------+
    | id      | bigint(20) | NO   | PRI | 0       |       |
    | user_id     | bigint(20) | NO   | MUL | NULL    |       |
    | item_id     | bigint(20) | NO   | MUL | NULL    |       |
    | expire_date | datetime   | NO   |     | NULL    |       |
    +-------------+------------+------+-----+---------+-------+
    4 rows in set (0.01 sec)
    

    プライマリーキーを設定したところ、エラーが起こらずに処理が流れるようになりました。

    2015年3月3日火曜日

    jenkinsでrubocop実行したらジョブがエラーになった時の対応

    rubocopで定期的にコーディングチェックをしたかったので、
    jenkinsで実行したらジョブがエラーになったので調べました。
    前提として、rubocopで警告が1個以上出る状態で実行しています。
    jenkinsのバージョンは1.599-1.1

    jenkinsのジョブでシェルの実行に以下を追加してジョブを実行する
    bundle exec rubocop --debug --rails --no-color --require rubocop/formatter/checkstyle_formatter --format RuboCop::Formatter::CheckstyleFormatter --out test/reports/checkstyle.xml
    
    実行してみたらこんな感じでfailureになりました。
    12:32:28 + bundle exec rubocop --debug --rails --no-color --require rubocop/formatter/checkstyle_formatter --format RuboCop::Formatter::CheckstyleFormatter --out test/reports/checkstyle.xml
    12:32:29 warning: parser/current is loading parser/ruby21, which recognizes
    12:32:29 warning: 2.1.5-compliant syntax, but you are running 2.1.4.
    12:32:36 For /var/lib/jenkins/jobs/test/workspace: configuration from /var/lib/jenkins/jobs/test/workspace/.rubocop.yml
    12:32:36 Inheriting configuration from /var/lib/jenkins/jobs/test/workspace/.rubocop_todo.yml
    12:32:36 Default configuration from /var/lib/jenkins/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/rubocop-0.28.0/config/default.yml
    12:32:36 Inheriting configuration from /var/lib/jenkins/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/rubocop-0.28.0/config/enabled.yml
    12:32:36 Inheriting configuration from /var/lib/jenkins/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/rubocop-0.28.0/config/disabled.yml
    12:32:36 Scanning /var/lib/jenkins/jobs/test/workspace/Gemfile
    12:32:36 Scanning /var/lib/jenkins/jobs/test/workspace/Rakefile
    12:32:36 Scanning /var/lib/jenkins/jobs/test/workspace/Capfile
    ・・・・
    12:32:53 Finished in 23.879888448 seconds
    12:32:53 Build step 'シェルの実行' marked build as failure
    

    シェルの内容を最後に必ずexit 0を返す以下に変更してみたが状況は変わらず。。
    bundle exec rubocop --debug --rails --no-color --require rubocop/formatter/checkstyle_formatter --format RuboCop::Formatter::CheckstyleFormatter --out test/reports/checkstyle.xml
    exit 0
    

    jenkinsについて調べてみると、jenkinsのシェルの実行は
    /bin/sh -xe
    で実行されているので、0でない終了コードが出た時点でスクリプトが終了するらしい。

    シェルの内容を以下に変更してみる
    /bin/sh -x
    bundle exec rubocop --debug --rails --no-color --require rubocop/formatter/checkstyle_formatter --format RuboCop::Formatter::CheckstyleFormatter --out test/reports/checkstyle.xml
    exit 0
    

    再度実行してみると無事に成功しました。
    12:44:42 + bundle exec rubocop --debug --rails --no-color --require rubocop/formatter/checkstyle_formatter --format RuboCop::Formatter::CheckstyleFormatter --out test/reports/checkstyle.xml
    12:44:43 warning: parser/current is loading parser/ruby21, which recognizes
    12:44:43 warning: 2.1.5-compliant syntax, but you are running 2.1.4.
    12:44:50 For /var/lib/jenkins/jobs/test/workspace: configuration from /var/lib/jenkins/jobs/test/workspace/.rubocop.yml
    12:44:50 Inheriting configuration from /var/lib/jenkins/jobs/test/workspace/.rubocop_todo.yml
    12:44:50 Default configuration from /var/lib/jenkins/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/rubocop-0.28.0/config/default.yml
    12:44:50 Inheriting configuration from /var/lib/jenkins/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/rubocop-0.28.0/config/enabled.yml
    12:44:50 Inheriting configuration from /var/lib/jenkins/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/rubocop-0.28.0/config/disabled.yml
    12:44:50 Scanning /var/lib/jenkins/jobs/test/workspace/Gemfile
    12:44:50 Scanning /var/lib/jenkins/jobs/test/workspace/Rakefile
    12:44:50 Scanning /var/lib/jenkins/jobs/test/workspace/Capfile
    ・・・
    12:45:07 Finished in 23.688404726 seconds
    12:45:07 + exit 0
    


    参考URL
    http://qiita.com/mechamogera/items/f689b95670127d5bf046

    2015年2月27日金曜日

    mixi iOS Training第4回に参加してきました

    またmixi のiOS Trainingに参加してきました。
    http://app-training.connpass.com/event/12019/

    まず前座でCocoaPodsの紹介がありました。
    http://cocoapods.org/
    rubyのgemみたいなものだそうです。
    プロジェクトを開くときには.xcode.xcodeprojじゃなくて.xcode.xcworkspaceを使う。

    今回はUITabControllerとUIViewでした。
    またメモったことをつらつらと載せます。

    https://github.com/mixi-inc/iOSTraining/wiki/2.2-UITabController

    ・UITabControllerをてっとり早く試すなら新規でプロジェクト作って実行してみるとよい。

    ・タブを増やす
    ViewControllerを追加してTab Bar Controllerからsegueをはる。
    view controllersを選択。

    ・根っこのcontrollerをtabbarcontrolllerにすることが多い

    ・ViewControllerをstoryboardで作らないでコードで作るのは
    ViewControllerの数が多くなってstoryboardがごちゃごちゃしてきたようなときとか。


    https://github.com/mixi-inc/iOSTraining/wiki/3.1-UIView

    ・ViewControllerは枠組みであって、目に見えているものはすべてUIView

    ・ViewCOntrollerは作成時にUIViewを一個もっている
    viewというやつ。これを消すとビルドできない
    viewの内容は画面サイズに合った真っ白い四角

    ・UIButton
    ボタンの表示内容はsetTitleでセットするのがデフォルト

    ・UIImageの画像の追加
    Images.xcassets開いて、そこに画像をドラッグアンドドロップ
    画像の種類
    2x retina
    3x iphone 6 plus
    1x それ以外

    ・Textview
    editableをYESにすると編集可能

    ・コードでViewを追加するのは出したり消したりってのを細かく制御したいときとか

    ・マルチサイズのデバイスに対応するにはautoLayoutで設定するので座標位置指定したりとかはあんまりやらない

    ・Viewのグルーピング(labelとbuttonとimageを一括で操作)をするとき
    Viewを一個作ってそれのsubviewに追加するような感じ


    そろそろお寿司が出るようです。

    2015年2月17日火曜日

    PowerDNSでDNSラウンドロビンしてみた

    社内の環境的にPowerDNSを使っているのですが、
    MySQLのslaveをDNSラウンドロビンで接続先を引けるようにしたかったので調べました。

    PowerDNSのバージョンは3.3.1。

    まずはCNAMEで登録してみました。
    CNAMEでは最初に登録したレコードしか引けませんでした。
    mysql> select * from records where id in(231,232);
    +-----+-----------+-------------------------+-------+------------------------------+------+------+-------------+-------+
    | id  | domain_id | name                    | type  | content                      | ttl  | prio | change_date | binip |
    +-----+-----------+-------------------------+-------+------------------------------+------+------+-------------+-------+
    | 231 |         1 | xxx-db-s.xxx.com        | CNAME | xxx-db1.xxx.com              | 3600 |   10 |        NULL |  NULL |
    | 232 |         1 | xxx-db-s.xxx.com        | CNAME | xxx-db2.xxx.com              | 3600 |   10 |        NULL |  NULL |
    +-----+-----------+-------------------------+-------+------------------------------+------+------+-------------+-------+
    2 row in set (0.00 sec)
    
    
    # nslookup xxx-db-s.xxx.com
    Server:  10.26.20.103
    Address: 10.26.20.103#53
     
    xxx-db-s.xxx.com canonical name = xxx-db1.xxx.com.
    Name: xxx-db1.xxx.com
    Address: 10.26.20.209
    


    次にAレコードで登録してみました。
    Aレコードだと登録した2つのレコードが引けるようになりました。
    mysql> select * from records where id in(231,232);
    +-----+-----------+-------------------------+------+--------------+------+------+-------------+-------+
    | id  | domain_id | name                    | type | content      | ttl  | prio | change_date | binip |
    +-----+-----------+-------------------------+------+--------------+------+------+-------------+-------+
    | 231 |         1 | xxx-db-s.xxx.com        | A    | 10.26.20.209 | 3600 |   10 |        NULL |  NULL |
    | 232 |         1 | xxx-db-s.xxx.com        | A    | 10.26.20.210 | 3600 |   10 |        NULL |  NULL |
    +-----+-----------+-------------------------+------+--------------+------+------+-------------+-------+
    2 rows in set (0.00 sec)
     
     
    # nslookup xxx-db-s.xxx.com
    Server:  10.26.20.103
    Address: 10.26.20.103#53
     
    Name: xxx-db-s.xxx.com
    Address: 10.26.20.209
    Name: xxx-db-s.xxx.com
    Address: 10.26.20.210
    


    参考URL
    https://twitter.com/satoh_fumiyasu/status/325039314205560832
    http://mailman.powerdns.com/pipermail/pdns-announce/2003-December/000008.html

    2015年2月13日金曜日

    mixi iOS Training第3回に参加してきました

    またmixiの勉強会に参加してきました。
    http://app-training.connpass.com/event/11598/

    今回もまずアプリエンジニアの方の話があり、先週のandroid trainingに続いての
    drivemodeの@KeithYokomaさんの話でした。
    iOSの勉強会でandroidメインの方だったので、少し微妙そうでした。。

    また講義の中でメモったことをつらつらと書いていきます。

    1.5 UIViewController3 ライフサイクル

    ・UIViewControllerの生成方法
    生成方法はいくつかあるが、どの初期化メソッドで呼ばれてもいいように、
    共通化した処理を作っておくのがよい。

    ・didReceiveMemoryWarningメソッドについて
    動画開いたりとか他のアプリでメモリが圧迫されたりとかしたときによばれる。
    ここで画像のメモリキャッシュをクリアしたりとかする。
    しないでほっとくとOS側にプロセスがkillされる。
    ちなみにiOS Simulatorのメニューの
    Hardware - Simulate Memory Warning
    から発生させることが可能。

    2.1-UINavigationController

    ・ツールバーとタブバーは似てるけど別物ですよ。

    ・UIBarButtonItemのstyleはplainを指定するか、ゴリゴリに実装するかが多い

    ・@selector
    メソッド名を関数にしてくれるような何かと思ってて。



    会も3回目になったので、だんだんとあ〜こういう動きするアプリあるなぁみたいなことを思ったりしてます。
    このまま続けていったら楽しい気がしてます。
    あと、最近mixiの勉強会参加してきたのブログばっかりなので、次は違うこと書きたいと思います。

    2015年1月29日木曜日

    mixi iOS Training第2回に参加してきました

    前回の第1回に引き続き、mixiで開催されたiOS Trainingの第2回に参加してきました。
    第1回の時のメモはこちら

    最初にまず5分程、hentekoさんからdeploygateの話がありました。
    ちなみにhentekoさんがobjective-c最初に勉強した時ははてなのドキュメントだったそうです。

    で、講義に入ったわけですが、今回も講師の方の説明を受けて、
    そのあとに自分で実習するという形式でした。

    まず最初にこちらの説明がありました。
    https://github.com/mixi-inc/iOSTraining/wiki/1.3-UIViewController1---UIViewController-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA(storyboard)
    UIViewControllerをstoryboardを使って作成していきました。

    以下、講義中にメモったものです。
    ・新しいファイルを作るときにはCocoa Touch classを選ぶとmとhを両方作ってくれる
    ・storyboardにラベルなどが配置できないときはstoryboardの方をダブルクリックして大きくすると配置できる
    ・起動時に表示される画面はLaunchScrean.xibで設定できる。昔は画像でやってた(xibでやれるのはxcode6から)
    ・storyobjectでひも付けたobjectを削除したいときはstoryboardから×で削除する必要あり。
     ソースコードでプロパティ消すだけだと実行時にクラッシュするらしい
    ・ボタンタップした時のアクションは、5年くらいやってるけどtouch up inside これ一択らしい
    ・カーソルあわせてcommand+clickでソース見れる
    ・ソースのところで指2本で左右にフリックすると前後に開いてたファイルが開ける

    次にこちらの説明がありました。
    https://github.com/mixi-inc/iOSTraining/wiki/1.4-UIViewController2-ModalViewController-(storyboard)

    以下、講義中にメモったものです。
    ・モーダルの出し方いくつかあるが、inspectorをいちいち見ないとわからないのでコードでやることが多い
    ・モーダルを閉じるときは自分で自分をdismissしないようにする。
    ・delegateの利用用途は、モーダルで入力した内容を呼び出し元に反映させたりするときとか
    ・delegateパターンでのモーダルがわのプロパティはweakにしておかないと、めっちゃクラッシュするらしい。


    普段の業務でやらない領域なだけに、講師の人がやりながら説明してくれるのを
    見ながら勉強できるのはなんかいいなぁと感じています。また次回も参加したいですね。

    2015年1月16日金曜日

    mixi iOS Training第1回に参加してきました

    mixiで開催されたiOS Training第1回に参加してきました。
    http://app-training.connpass.com/event/10754/

    内容はconnpassに貼ってあるgithubのドキュメントに沿って講師の方に説明をしていただいて、
    それから用意してあったプログラムをテストが通るように修正しながら学んでいく実践形式で進められました。

    まず最初にあったのはスポンサー?のFind Job!の宣伝でした。
    なんか面談に行くとQUOカード5000円分くれる券をもらえました。

    講義の中でメモったことを以下に載せていきます。

    ・iOSについて
    https://github.com/mixi-inc/iOSTraining/wiki/0.1-iOSについて
    iOSヒューマンインターフェイスガイドライン
    はエンジニアに限らず絶対読んでおいてほしいとのこと。

    ・Xcode最初のステップ
    https://github.com/mixi-inc/iOSTraining/wiki/0.2-Xcode最初のステップ

    ショートカットをいくつか教わりました。
    実行
    command + r

    シミュレータのwindowサイズ変更
    command + 1 or 2 or 3

    テスト実行
    command + u


    ・Objective-C入門
    https://github.com/mixi-inc/introduction-for-objective-c
    https://github.com/mixi-inc/iOSTraining/wiki/1.1-Objective-Cの基礎

    print debugのやり方
    NSLog(@"here!! %@", obj);
    %@のところがobjで置き換えられる

    Xcodeの行番号の表示
    Xcode - Preferenceから
    Text EditingでLine Numbersにチェックを入れる。


    参加した感想としては、普段サーバーサイドのプログラムしか書いてない自分には
    とてもいい機会がもらえてよかったなぁと思いました。
    ただ、ここに参加するだけでは全然書けるようにはならなそうな気もするので、
    結局は自主トレ必須ですね。でもやれるだけやりたいと思います。

    あと、最後の時間にテスト通るようにしましょうって時間があって、
    なんかその時間はちょっとタイムアタックみたいな気分がして楽しかったです。

    次回は1/28だそうです。