ラベル rails の投稿を表示しています。 すべての投稿を表示
ラベル rails の投稿を表示しています。 すべての投稿を表示

2013年9月5日木曜日

関西Ruby会議05でのプレゼンの製作について

■概要


先日、関西Ruby会議05が開催されました。大変面白く為になる一日でした。実行委員 / スタッフの皆様、スピーカーの皆様お疲れ様です!

さて幸運にも、そのイベントで招待講演をさせて頂きました。公での40分・100人超という、私にとっては未体験ゾーンでのプレゼンです。

当日のプレゼンの出来は、自分ではわかりませんが、それなりに工夫をして作ったのは間違いないので、吐き出せるものは吐き出しておこうと思い、このエントリを書きはじめました。

少し長いですがお付き合い頂ければと思います。

ちなみに当日の発表資料はこちらです。合わせて御覧頂けたら幸いです。









■きっかけ


2013/05/12 12:15。その時私は生駒山麓公園という所で、子供とアスレチックをしておりました。



すると突然、実行委員の @agilekawabata さんからTwitterのDMが届き
「関西Ruby会議(08/31)にて講演どうですかー?」
ときたので
「お、イイですね!させて頂きます。」
と軽い気持ちで答えてしまいました。

その時、まさか招待講演という重責とはつゆ知らずでしたが、受けてしまったので何とかしようと考えました。
正気ですか?」と叫びたくはなりましたが。

■書籍


以前よりRuby会議やその他のカンファレンスでの素晴らしい発表を見て、プレゼンをするという事に興味を持った事もあり、社内では過去三年ぐらいプレゼン勉強会を主催しています。元々社内で「プレゼンテーションZENが面白い」といった所、賛同してくれる人がおり勉強会に発展しました。

読まれた方も多いと思いますが、上記の「プレゼンテーションZEN」という書籍が
(出来ているかどうかは別にして)私のプレゼンスタイルに与えた影響はかなり大きいです。



後もう一冊非常にオススメなのが、ナンシー・デュアルテの「ザ・プレゼンテーション」です。根底にある物は同じように感じますが、また異なった視点でプレゼンを語っており、本当に為になる一冊です。













いずれの本も「スライドの作り方/Power Point(keynote)の使い方」といったテクニックより、
  • 何故プレゼンをするのか?
  • 誰の為のプレゼンであるか?
  • 論理 vs パッション
  • ストーリーで語る事の重要さ
  • どのようにすれば印象に残るか? ...etc
といった部分が多く語られており、本当に素晴らしい書籍だと思います。未読の方は是非読んで欲しいな~と思います。

■製作


5月には講演が決まったのですが、その後色々ありまして、話のプロットを考え始めたのは、8月の上旬に早めの夏休みをとり家族で旅行した後です。

そこから通勤や休みの日に構成を作って行きました。この段階では全て頭の中で考え、ある程度まとまってからiphoneのメモにテキストを作成しました。

上記の書籍でも語られていますが、最初の段階からデジタルな世界で考えるのは、あまり良くないように感じます(雑音が多いですから!)。ゆっくりネットの無い状態で、心の声と向き合う時間を持つ事が大切だな~と今回痛感しました。

...

その後また色々あって、実際にスライドを作成し始めたのは、2013/08/23の夜からです。何と本番の一週間前です!かなりヒヤヒヤしました。

過去の経験から100枚前後のスライドが必要になるので汽車犬のように作成しました。









ただこれも過去の経験から、私のスタイルと(高くない)スライドの精度なら、話が決まっていればスライド製作はあまり時間がかからないというのもありました。
土日と断続的に作業を続け、日曜の夜にはα版が完成しました。

そこから昼休み、夜等にシャドープレゼンを繰り返し、しゃべりとスライドを馴染ましていきました。
この練習の過程で、120枚ぐらい作ったスライドから優先度の高いトピックを残し、最終的には93枚
のスライドになりました。

このシャドープレゼンの過程では、

  • トピックの取捨選択
  • スライドを俯瞰してのトピックの順番の決定
  • しゃべりと馴染まないスライドの、分割 / 統合 / 破棄の実施
を行ないα版が、β版ぐらいにはなりました。

発表直前まで、スライドは微調整しました。特に小さいフォントを大きくし、見やすくというのを心がけました。

■今回取り入れて良かった事


今回社内のような、良く知っている人向けのプレゼンでは無いので、レビューしてもらう事が重要だと思いました(ex. 面白くない冗談、内輪受けのネタに走っていないかとか)。

まずβ版の段階で、妻(非IT)にスライドを見てもらいながら話そうと思っている事を説明しました。
これは"かなり"効果がありました。

意味不明な写真や、気持ち悪い色使い、良く分からないトピック等、沢山の指摘をしてもらいました。また「以前聞いた話では、タイムゾーンの話と英語の話が印象的だった」というアドバイスをもらいコンテンツに含める事にしました。










また社内のプレゼン勉強会のメンバーには、実際のプレゼンをみてもらいました。
ここでも本当に重要な指摘をしてもらいました。意味不明な写真や語彙について、沢山のアドバイスをもらいました。こちらもスライド/構成/喋りの精度を上げていくのに効果がありました。

森田くん、寺島くん、酒井さん、本当にありがとう。

反省点としては、このレビューをもっと早く受けていれば、もっと改善できた所です。
スケジュール管理がなっていない自分に反省です。

■練習


前述のようなバタバタしたスケジュールでしたが、プレゼンの練習は、通しで何度も行ないました。
概ね5日間で、10回ぐらい通しはしたと思います。また最初の~10分を上手く乗り越えれば、後は
何とかなると思い、冒頭は少し重点的に練習しました。

私は、喋りに対して苦手意識があるので(特にアドリブ)、練習する事により、その不安を払拭する事ができると感じます。またとっさの問題発生時にも、練習により対処方法の平均点を向上できるとも思います。

滑舌を少しでも改善したり、言い難い言葉を他の言葉に置き換えたり、間を考えたり ...etc
スライド製作より、練習という過程の方がよっぽど大事だな~と今は感じます。

また練習すると「次のスライドの内容を少し話してからページ切り替え」が出来るようになります。
これは結構良いテクニックだと思います。

# もっと早く準備します。反省。

ちなみに本番のプレゼン時間は発表者用ツールによると37.5分でした。だいたい練習通りでの終了となりました。

■構成


プレゼン全体の構成は、もっと上手くできるようになりたいです。今回40分という尺を頂いたので、トピックのバランスや順番については、もっと工夫ができたはずと悔やんでいます。

ただ要所要所で考えた事もあるので書いておきます。

・冒頭の話方

プレゼンは、最初の10~20秒で聴衆の印象が決定するというのを聞いたことがありますが、残念ながら私は、最初から笑いを取るのは上手くありません。

だから危険な賭けをするよりは、普通の話題で初めて、少しずつ空気を温める作戦にしたいと考えました。

恐らく私のことは知らない人がほとんどなので、冒頭では、まず皆にとって共通の話題をチョイスし
(ruby言語/Ruby Kaigi)少しでも一体感を作りたいと考えました。また実行委員/スタッフの方々への謝意を伝えたかったので、これも話題としてチョイスし、拍手という体を動かす行為をしてもらう事により、少しでも空気をほぐそうと考えました。

・自己紹介










今回は自己紹介を冒頭に持ってくる構成はやめようと思いました。
40分間あるので、そこそこゆったりと時間が使える事もありますし、最初から「オレがオレが」という
構成にしてしまうと「誰の為のプレゼンか」を自分自身見失ってしまいそうな気がしたからです。

自己紹介に家族の写真を使うのは好きです(自分の中でのお約束にしてます)。人物像・状況を言葉で伝えるよりも、簡単に伝えられると考えています。

・Railsコントリビュータになるまでの話

ここは今でも構成上どうだったのか悩んでいる部分です。
というのも冒頭~Railsコントリビュータになるまでの尺が、何度練習しても10分強になるからです。
人によっては、ここまでで飽きてしまうのではと恐れました。

最初は15分かかる内容だったので少しスライドを捨てました。少し長いとも思いましたが、ストーリー仕立てという事もあり(編集しにくいので)そのままにしておきました。

・思い出のコミットの話

今回Ruby会議という事もあり、聴衆の層が分かりそうな気もしますが、中々分かりかねる部分もありました。

そん中で、私の活動の成功/失敗やコミュニティーという部分が、外から見た時に分かりにくいと思うのと、少しはテクい話しをしないと納得頂けない方もいるのではと思いましたw










ちなみに練習時の指摘を元に「rubyは知っているが、rails/githubについて名前は知っているが深くは知らない」という人に合わせ、語彙の変更をしました(うっかりプルリクとか言った気がしますが...)

・まとめ

好きなプレゼンなので、是非「マッド・カッツの30日間チャレンジ」の話を紹介したかったのと、自分自身の見解や、これからコミュニティーやってくる人への話をしたいと思いました。










少し説教臭い語り口だったと思うので「どうかな?」とも思いましたが、これぐらいの方が選んだ話の終わりとしては適当かなとも思い話の結末といたしました。









■最後に


自分なりには、持てる力を注ぐ事ができた講演ではありました。
次機会があれば、反省点を踏まえ、もっと上手くなりたいな~と感じました。

皆さん聞いて/読んで頂きありがとうございました。

2013年8月18日日曜日

ActiveRecord::Core.generated_feature_methods が何をしているか?

今日参加させて頂いたKobe Rubyist Meetup 1stで話題になった、
ActiveRecord::Core.generated_feature_methods の意味が良く分からない問題を追跡してみました。

■疑問


@sutetotanuki さんより下記のコードの意味が分からないとの質問がありました。
以前から私も良く分からないコードだな~と思っていたのですが、理由を良く知りませんでした。
 97       def generated_feature_methods
 98         @generated_feature_methods ||= begin
 99           mod = const_set(:GeneratedFeatureMethods, Module.new)
100           include mod
101           mod
102         end
103       end
moduleをその場で生成しincludeしているだけ。何の役に立つのか?

■調査した結果


generated_feature_methods を呼び出しているのは、少し上の initialize_generated_modules メソッド とassociations/builder系 と nested_attributes.rb です。

まず initialize_generated_modules メソッドは

activerecord/lib/active_record/core.rb より
 91       def initialize_generated_modules
 92         super
 93
 94         generated_feature_methods
 95       end
となっており、generated_feature_methods を呼び出す前に、さらに上位のメソッドを呼び出しており、 その中で@generated_attribute_methodsが生成されています。

activerecord/lib/active_record/attribute_methods.rb より
 62       def initialize_generated_modules # :nodoc:
 63         @generated_attribute_methods = Module.new { extend Mutex_m }
 64         @attribute_methods_generated = false
 65         include @generated_attribute_methods
 66       end
これにより generated_attribute_methods が返すModuleは、generated_feature_methodsが返すModuleより継承ツリー上、必ず上位になります。

一方でassociations/builder系 と nested_attributes.rbでは、アクセサを生成する為のmoduleとして利用されている事がわかります。

activerecord/lib/active_record/associations/builder/association.rb より
 85     def define_accessors(model)
 86       mixin = model.generated_feature_methods
 87       define_readers(mixin)
 88       define_writers(mixin)
 89     end
これにより属性用のメソッドは、アソシエーション用のメソッドより継承ツリーでは上位で生成される。言い換えるとアソシエーション用のメソッドが優先して呼び出されるようにしたいという意図が見えると思います。

実際、関係がありそうなコミット
を見てみると、そのようなコミットコメントが書かれています。
Instead of generating association methods directly in the model
class, they are generated in an anonymous module which
is then included in the model class. There is one such module
for each association. The only subtlety is that the
generated_attributes_methods module (from ActiveModel) must
be forced to be included before association methods are created
so that attribute methods will not shadow association methods.
 テストケースには、さらによく分かるコードが残っています。
333   def test_association_methods_override_attribute_methods_of_same_name
334     assert_equal(developers(:david), computers(:workstation).developer)
335     # this next line will fail if the attribute methods module is generated lazily
336     # after the association methods module is generated
337     assert_equal(developers(:david), computers(:workstation).developer)
338     assert_equal(developers(:david).id, computers(:workstation)[:developer])
339   end
なるほど!深い理由がある事が分かりましたw

2012年6月24日日曜日

ActiveRecord自体のテストケースをOracleで動かす

■概要

ActiveRecord自体のテストケースは通常sqlite3/mysql/postgresqlで実行しますが、oracleで実行したくなり調べましたが少し手こずりました。手順を残しておきます。

■oracle-xeインストール準備

・swap領域が足りないので追加
# dd if=/dev/zero of=/swap.extended bs=1M count=1024
# mkswap /swap.extended
# swapon /swap.extended

# cat /proc/swaps # 確認
Filename                        Type            Size    Used    Priority
/dev/vda2                               partition       2096472 19024   -1
/swap.extended                          file            1048568 0       -2

# vim /etc/fstab # 再起動時のおまじない
...
/swap.extended          swap                    swap    defaults        0 0

■oracle関係インストール

・ここからoracle11g xeをダウンロード
  http://www.oracle.com/technetwork/database/enterprise-edition/overview/index.html

・oracle-xeインストール
# unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
# cd Disk1
# rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm
# /etc/init.d/oracle-xe configure
入力は、9080(8080は他の用途で利用している...) => 1521 => パスワード => y
# /etc/init.d/oracle-xe status
・oracle clientインストール
  http://www.oracle.com/technetwork/jp/topics/index-099943-ja.html
# rpm -ivh oracle-instantclient11.2-basic-11.2.0.2.0.x86_64.rpm
# rpm -ivh oracle-instantclient11.2-devel-11.2.0.2.0.x86_64.rpm
# rpm -ivh oracle-instantclient11.2-sqlplus-11.2.0.2.0.x86_64.rpm
■ユーザ設定
・環境変数を設定
$ vim ~/.bash_profile
export LD_LIBRARY_PATH=/usr/lib/oracle/11.2/client64/lib/:$LD_LIBRARY_PATH
export PATH=/usr/lib/oracle/11.2/client64/bin/:$PATH
export NLS_LANG=JAPANESE_JAPAN.AL32UTF8
$ source ~/.bash_profile
・テスト用ユーザ作成
$ sqlplus system/パスワード@localhost:1521/XE
SQL> create user arunit identified by arunit default tablespace USERS temporary tablespace TEMP;
SQL> create user arunit2 identified by arunit2 default tablespace USERS temporary tablespace TEMP;
SQL> grant connect,resource to arunit;
SQL> grant create session to arunit;
SQL> grant create synonym to arunit;
SQL> grant connect,resource to arunit2;
SQL> grant create session to arunit2;
SQL> grant create synonym to arunit2;

■gem準備

$ gem install ruby-oci8
$ git clone git://github.com/rsim/oracle-enhanced.git
$ git checkout -b rails4 origin/rails4
$ cd /home/kennyj/rails/activerecord
$ ORACLE_ENHANCED_PATH=/home/kennyj/oracle-enhanced bundle update

■テスト実行

$ ARUNIT_DB_NAME=localhost:1521/XE ARCONN=oracle \
  ORACLE_ENHANCED_PATH=/home/kennyj/oracle-enhanced \
  ruby -Itest:lib test/cases/schema_dumper_test.rb

2012年5月28日月曜日

ruby/rails勉強会54thで、ライトニングトークスさせて頂きました!

 2012/05/26に、Ruby関西様主催の「ruby/rails勉強会54th」で、ライトニングトークスをさせて頂きました。

スライドはこちら

発表の是非は皆様のご判断を仰ぐとして、今後の為に思ったことを記載しておきます。

■練習・リハーサルは重要


  • 前日に3時間程度練習しました。少ない!と言われるかもしれませんが、必要以上に緊張せずにはすみました。
  • リハーサルにて時間が長すぎる事が分かったので、結果9枚(1/4程度)スライドを捨てました。中心的なメッセージ以外のくだりは、思い切って外しました。

■前回某所でのLTでは、練習では5分丁度だったのに、実際には  3.5分程度になってしまった。


  • 練習をしてくるのは当然だが、使える機能は利用すべきと思った。
  • マルチモニタ機能で、プレゼン画面と発表者用をわける。
  • ちら見程度でも、時間の把握と次のスライドがわかるとよい。次のスライドが分かれば、先に話を進めてからスライドを切り替えるという、進め方を確実にする事が可能。
  • もっと時間をかけて練習すれば、不要なのは理解しているのですが現実との兼ね合いで妥協。
  • 音楽における”暗譜”と似てますね。

■反省点


  • 5分という制約の中で、この題材は適切だったのか少し反省。
  • 話題を詰め込みすぎて、喋りが慌ただしかったと思う。
  • リモコン?が無いので、画面切り替え時にPCを操作しなければいけなかった。結果目線を落とす必要があり、また体を自由に使って表現が難しかった。
  • スライドは自分のしゃべりを支える物と考えているのですが、いざslideshareにあげてみると、よく分からんだろうなと思いました。
  • 「プレゼンテーションzen」の影響うけてますよね?と感想を頂いた。全くその通りで指摘頂き嬉しい半面、さらに精進して影響を消化したいなと思いました。


2012年5月1日火曜日

rails自体の開発環境を作る2012


■概要
さくらvpsを新プランに乗り換えたので、またまた"rails自体"の開発環境を作ります。

■パッケージ管理・導入(centos6.2 x86_64 2Gプラン)

○パッケージの最新化
# yum -y update
(yum -y upgrade)

○必要そうなパッケージをインストール
# yum -y install git nmap telnet

# yum -y install screen zsh

(# yum -y install httpd httpd-devel)

# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
# yum --enablerepo=remi,remi-test -y install mysql mysql-server mysql-devel

# yum -y install sqlite sqlite-devel

# rpm -Uvh http://yum.postgresql.org/9.1/redhat/rhel-6-x86_64/pgdg-centos91-9.1-4.noarch.rpm
# yum -y install postgresql91 postgresql91-contrib postgresql91-devel postgresql91-libs postgresql91-server

# yum --disablerepo=pgdg91 -y install libevent libevent-devel memcached memcached-devel

# yum -y install openssl-devel curl-devel readline-devel zlib-devel libxml2 libxml2-devel libxslt-devel libyaml-devel libffi-devel
# yum -y install java-1.6.0-openjdk java-1.6.0-openjdk-devel java-1.6.0-openjdk-src

(参考) http://www.if-not-true-then-false.com/2010/install-mysql-on-fedora-centos-red-hat-rhel/
(参考) http://www.oss-d.net/postgresql/9.1

■設定

○日本語化
# vim /etc/sysconfig/i18n
LANG="C" から LANG="ja_JP.UTF-8" に変更

○不要デーモンの停止設定
# chkconfig auditd off
# chkconfig haldaemon off
# chkconfig mdmonitor off
# chkconfig messagebus off
# chkconfig netfs off
# chkconfig restorecond off
# chkconfig smartd off

(参考) http://tanaka.sakura.ad.jp/archives/001065.html

○FW設定
# system-config-firewall-tui
SSH/HTTPS/HTTP/3000(tcp)
後は未設定

○時間同期設定
(さくらVPSでは最初から設定されていました)
# yum -y install ntp
# vim /etc/ntp.conf
# ntpdate ntp.nict.jp (とりあえず一旦近づけておく)
# /etc/init.d/ntpd start
# chkconfig ntpd on

○selinux停止
(さくらVPSでは最初から設定されていました)
# vim /etc/sysconfig/selinux
SELINUX=disabled
# reboot

○作業用ユーザ作成
# useradd kennyj
# passwd kennyj

○sudo設定
# /usr/sbin/visudo
(一番下に追記)
kennyj  ALL=(ALL)       ALL

○ssh設定
# vim /etc/ssh/sshd_config
(42行目)
PermitRootLogin no
(47行目)
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
(65行目)
PermitEmptyPasswords no
PasswordAuthentication no

# /etc/init.d/sshd restart

# su - kennyj
$ ssh-keygen -t rsa
$ mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
(秘密鍵をローカルにダウンロード。秘密鍵のみでログインできる事を確認する。)
$ rm ~/.ssh/id_rsa
$ exit

○postgresql準備
# service postgresql-9.1 initdb

○mysql準備
# vim /etc/my.cnf
(文字列エンコーディングをUTF-8に設定)
[mysqld]
...
character-set-server = utf8

[mysqld_safe]
...
character-set-server = utf8

[mysql]
...
default-character-set = utf8

# mysql_install_db
# service mysqld start
# mysql_secure_installation

○必要に応じてサービス起動設定
(# chkconfig httpd on)
# chkconfig mysqld on
# chkconfig postgresql-9.1 on
# chkconfig memcached on

○再起動
# reboot

○サービス稼動確認
# ps aux | grep -E 'http|postgre|mysql|memcache'

■rails環境構築

○javascript関係インストール
# wget http://nodejs.tchol.org/repocfg/el/nodejs-stable-release.noarch.rpm
# yum localinstall --nogpgcheck nodejs-stable-release.noarch.rpm
# yum install nodejs-compat-symlinks npm

(# npm install express -g)
(# npm install jade -g)
(# npm install socket.io -g)
# npm install coffee-script -g

(参考) https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager

○ruby関係インストール

(kennyjユーザで)
$ curl https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer | bash -s stable
$ source ~/.rvm/scripts/rvm
$ rvm install ree-1.8.7-2012.02
$ rvm install 1.9.3-p194
$ rvm install jruby-1.6.7

$ rvm use --default 1.9.3
($ rvm ree,1.9.3,jruby do gem install rails --no-rdoc --no-ri)

■rails開発環境

○mysqlの設定
$ mysql -u root
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*  to 'rails'@'localhost';
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost';
mysql> flush privileges;
mysql> quit

○postgresqlの設定
$ sudo -u postgres createuser --superuser $USER

○github公開鍵の準備
(参考) http://help.github.com/win-set-up-git/

○gitの設定
$ git config --global user.name kennyj # 名前
$ git config --global user.email kennyj@gmail.com # メールアドレス

○gitの補完機能設定
$ cd $HOME
$ wget https://raw.github.com/gitster/git/master/contrib/completion/git-completion.bash -O .git-completion.bash
$ vim $HOME/.bashrc
source $HOME/.git-completion.bash
PS1='\w$(__git_ps1 "(%s)")\$ '

$ souce ~/.bashrc

○rails開発環境
$ git clone git://github.com/(自分)/rails.git (先にgithub上でforkしておく)
$ cd rails
$ gem install pg -- --with-pg-config=/usr/pgsql-9.1/bin/pg_config
$ bundle update
$ bundle exec rake mysql:build_databases
$ bundle exec rake postgresql:build_databases
○hstore準備
$ psql activerecord_unittest
> CREATE EXTENSION hstore;
> \q
$ psql activerecord_unittest2
> CREATE EXTENSION hstore;
> \q
○テスト稼動確認
$ cd ..
$ bundle exec rake (テスト稼動確認)

○docrailsも準備
$ cd $HOME
$ git clone git://github.com/lifo/docrails.git

○適宜関連gemの開発環境
$ git clone git://github.com/(自分)/mail.git
$ git clone git://github.com/(自分)/journey.git
$ git clone git://github.com/(自分)/sprockets.git
$ git clone git://github.com/(自分)/sprockets-rails.git
...

2012年3月29日木曜日

ActiveRecord自体のテストケースを実行する際にDBを選ぶ方法

■概要
ActiveRecord自体のテストケースを、"個別に"実行する際のデフォルトDBは、sqlite3です。これを切り替える方法が、長らくわからず時間を浪費していました。

■方法
わかってしまえば簡単です。ARCONNで指定できます。
$ cd activerecord
$ ARCONN=mysql2 ruby -Ilib:test test/cases/base_test.rb

2012年2月19日日曜日

Rails contributorsはどこにいるのか?

■概要

久しぶりの更新になります。最近はもっぱらgithubでの活動がメインになってしまいました。

色々なコントリビュータとやりとりをしていると「この人は現地で今何時なんだ?」と思う事が増えました。という事でまずコントリビュータがどこにいるのか調べてみました。

■説明

さてどうやったら調べられるか考えたのですが下記のステップでデータを作成しました。
  1. github APIを利用して、rails contributorsをリストアップします。 https://api.github.com/repos/rails/rails/contributors 
  2. github accountの束が手に入るので、こちらもgithub APIを利用して、profile情報を取得します。 例えばDHHなら、https://api.github.com/users/dhh
  3. 2. で取得した情報を良く見るとlocation情報に、"Chicago, USA"と書いてあるのでこれを緯度経度情報に変換できれば、やりたい事を実現できます。
  4. 色々調べてみると、google maps API v3のジオコーディングリクエストを利用すれば、目的が達成できる事がわかりました。 http://code.google.com/intl/ja/apis/maps/documentation/javascript/services.html#Geocoding
  5. ここまでで得た情報をgoogle maps上にプロットする。
■結果
(全体)都合によりTop300でローケーションが判明した人のみプロットしました。貢献数が多い人ほどZIndexを優先にし、画像サイズも変えてみました。世界に広がっていますね。アフリカ以外 ^o^

(北米)アメリカといっても広いんですね。色々な地域から参加してます。

(ヨーロッパ)アメリカよりも多いぐらいの人が参加していますね。ちょっと意外でした。josevalimさんってここなんですかね?

(南米)最近非常に活発なのは、この地域だと思います。見知った顔が一番多いです^o^

 (アジア)アジアは少なめですが、インドが非常に活発です。日本からは、松田明さんと恥ずかしながら私めがエントリーです。

■まとめ
プロットしてみると改めて、世界から参加しているのがわかりました。また各種APIを組み合わせて物を作るというのも面白いですね!


2011年11月23日水曜日

こうして僕はrailsを遅くした。そしてそこそこ直した。


最近blogの更新が途絶えがちですが、githubが面白くて(汗)...

先日、ruby on rails 3.1.2と3.1.3が矢継ぎ早にリリースされたのですが、実は関与者の一人だったりします。自戒の意味もかねて、経緯とかを書いておきます。

・2011/10/31 無作為に選んだissueを直そうと思った。

このissueを調べ始めたのですが、
色々調べてみるとmysqlのdescribeの問題という事が判明し、結果的にschema dumperの出力がバグってるという事が分かった。

そこで、describeを使わない形(informationスキーマを利用)で修正した。

・2011/11/06 master/3-1-stableにマージされた。

その後やりとりがあって、直ってよかったねという事で取り込まれた。

・2011/11/18 rails 3.1.2がリリースされた。

そりゃま~、ARは初めてだったので嬉しかったです(リリースノートにも名前が載ったし)。

・2011/11/18深夜 問題発覚。

ActiveRecord 3.1.2 takes 10 times slower than 3.1.1」というissueがあがる。
良く見てみるとmysqlとあるじゃないか!というのも前のリリースからmysqlについて修正したの私だけ(汗)

その後、某スペイン人(Christos Zisopoulosさん)とのやりとりで、"多くのデータベースが存在するmysql"の場合、遅くなる事が判明。

schema dumperの時のみ、元の修正を利用する、pull requestが取り込まれましたが、
抜本解決ではないので、"show index from"を利用する形で修正を進めた。

・2011/11/19 早朝 修正完了。
・2011/11/19 AM9時頃 某スペイン人により効果が確認され、pull requestした。

その後、railsコミッタのjonleightonにマージしてもらう(master/3-1-stable)。

・2011/11/21 sprockets等他の問題も修正され、rails 3.1.3がリリースされた。

ちなみにsprocketsは
 「windows環境でasset pipe lineが失敗する」
 「ファイルの更新が反映されない場合がある」
問題があり、最終的に2.0.xにダウングレードされました。

途中「速くリリースしろゴラ!」とか言う人がいてビビッタ。

・2011/11/23

超大規模なデータセットの場合、問題がある可能性がありそうな為、再度「show create table」を利用する形で調整中。

・2011/12/5


「show create table」を利用する形での実装が、rails 3.2系にマージされました。


・2011/12/6


さらにrails 3.1系にもback portされました。


■雑感

・世界中で困っている人がいるかと思うとかなりびびった。某スペイン人には多謝。
・この手の、量に対するテストをどう実施していくかは、そもそも根本的な問題。
・私の嘘英語でも何とかやっていけてるのが驚異的。
・gitはコマンド多すぎるが、かなり便利。

2011年10月21日金曜日

githubで既にあるIssueにPull Requestをくっつける方法

概要

githubではPull Requestを送信する時に自動的にIssueも作成されます。 しかし「既にあるIssueにPull Requestをくっつける」という事がしたくなる場合があります。

説明

困ったときのStackoverflowによると、githubはWeb-APIが充実しておりそれを利用すると、実現できるようです。参考ページを参考にするとUnix上でcurlを利用してwebリクエストを送信すると簡単でした。
例
$ curl -k \
         -d "pull[base]=master" \
         -d "pull[head]=master" \
         -d "pull[issue]=1234" \
         -u "kennyj:xxxxx" \
         https://github.com/api/v2/json/pulls/rails/rails

-k SSL証明書の問題?を避ける
-d "pull[base]=master" 送信先のbranch名
-d "pull[head]=master" 送信元のbranch名
-d "pull[issue]=1234" バグ票番号
-u "kennyj:xxxxx" ユーザ名とパスワード
https://github.com/api/v2/json/pulls/rails/rails 送信先のユーザ名とリポジトリ名
無駄にIssueを増やさない為にも知ってて損はなさそうです。

参考

How do you attach a new pull request to an existing issue on github?

2011年9月20日火曜日

spec実行時にdb:test:prepareを呼び出したくない。


■概要

(激しく既出感ありですが。。)何年もrailsやってますが、正しく理解できていなかった事の一つに

  rake spec(test)すると、処理の一環としてdb:test:prepareタスクを呼び出す

という挙動があります。
通常問題にならないのですが、db:test:prepareが、db/schema.rbの情報を元にデーターベースを作成する為、railsが認識できないような項目は抜けて落ちてしまいます。

  • 関数適用したインデックス
  • トリガーやファンクション
  • 別スキーマに作ったオブジェクト ...etc

なので

RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate

してからrake specする事を前提に、db:test:prepareを呼び出さずにspecを実行する方法を模索しました。

■案1 db:test:prepare自体を書き換える

参照先にそのまんまの解決策が書かれています。
Rakefileでtask削除用のメソッドを用意します(load_tasksの前に!)。
Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

lib/tasks/db/test.rakeとかを作って、実際にタスクを上書きします
Rake.application.remove_task 'db:test:prepare'

namespace :db do
  namespace :test do 
    task :prepare do |t|
      # rewrite the task to not do anything you don't want
    end
  end
end

参考 http://stackoverflow.com/questions/1097845/how-to-prevent-rake-test-to-call-task-dbtestprepare

■案2 自力でspecを実行する

db:test:prepareを壊すのは怖いので...という方にはこのやり方

lib/tasks/spec.rakeとかを作って
require 'rake'
require 'rspec/core/rake_task'

namespace :spec do
  RSpec::Core::RakeTask.new('no_prepare_db') do |t|
    t.pattern = ['spec/**/*_spec.rb']
  end
  namespace :no_prepare_db do
    %w(controllers helpers lib mailers models requests routing views).each do |dir|
      RSpec::Core::RakeTask.new(dir) do |t|
        t.pattern = ["spec/#{dir}/**/*_spec.rb"]
      end
    end
  end
end
で、rake spec:no_prepre_dbや、rake spec:no_prepare_db:modelsで、db:test:prepareを呼び出さずに実行できます。

参考 http://old.nabble.com/db%3Atest%3Aprepare-interfering-with-rake-spec-pattern-td31075510.html

2011年8月23日火曜日

capybara-webkitを動かす 2011/08/23時点版

■概要

こちらの素晴らしい記事では、capybara-webkitを利用して、headlessでjsが動く環境を紹介されています。

capybara-webkitのこれまでリリースされているバージョン(~0.5.0)では、capybara1.0.0系への依存が解決できない為、抗う方法をご紹介されています。が、0.6.0からは上手く依存関係を解決されるようになりました!

■手順

こちらと同様ですが、Xvfbとqtの当たらしいバージョン(qt47)をインストールしておきます。
qt47にする理由はphantomjsも動かしたいからです ^o^

$ sudo yum -y install firefox ★ seleniumで動かす必要があれば
$ sudo yum -y install xorg-x11-server-Xvfb xorg-x11-fonts*
$ sudo vim /etc/yum.repos.d/atrpms.repo

[atrpms]
name= CentOS-$releasever - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/testing/
gpgcheck=1
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms
enabled=0

$ sudo rpm --import http://packages.atrpms.net/RPM-GPG-KEY.atrpms
$ sudo yum -y install sqlite --enablerepo=atrpms ★依存関係からインストールする必要がある?
$ sudo yum -y install qt47-devel qt47-webkit qt47-webkit-devel --enablerepo=atrpms
$ sudo ln -s /usr/bin/qmake-qt47 /usr/bin/qmake (コンパイル時に必要とされるので予め作成)

でrailsプロジェクト側で

$ vim Gemfile
group :development, :test do
  ...
  gem 'capybara', '1.0.1'
  gem 'capybara-webkit', '0.6.0'
  gem 'headless', '0.1.0'
  ...
end
$ bundle install
$ vim spec/spec_helper.rb
...
require "capybara/rails"
require "capybara/rspec"
...
RSpec.configure do |config|
...
end

Capybara.javascript_driver = :webkit
$ vim spec/support/headless.rb
if %w(yes y on).include?(ENV['HEADLESS'])
  require 'headless'

  headless = Headless.new
  headless.start

  at_exit do
    headless.destroy
  end
end
$ vim spec/requests/index_spec.rb
# coding: utf-8

require 'spec_helper'

describe "Index" do
  describe "GET /" do
    it "/index.html", :js => true do
      visit "/"
      click_link "About your application’s environment"
      page.should have_content("No route matches")
    end
  end
end

$ HEADLESS=on bundle exec rspec spec/requests/index_spec.rb
Index
  GET /
    /index.html

Finished in 4.48 seconds
1 example, 0 failures
という訳でいい感じに実行できました~

2011年8月16日火曜日

(小ネタ)railsのセッションを復元する(rails2.3系で確認)

必要に迫られたので... メモ残しておきます。

$ irb
> require 'rubygems'
> require 'active_support'
> v = ActiveSupport::MessageVerifier.new('Railsのsecret', 'SHA1')
> v.verify('session文字列')

※1 Railsのsecretは、initializer/session_store.rb
※2 session文字列は、cookieから取得

ちなみに得られる結果はrack.sessionと同じです。

2011年8月13日土曜日

ruby1.9時代にrcovは使ってはいけない。simplecovを使おう!

■概要

rubyにおけるテスト網羅率の定番ツールといえばrcovですが、どうもテストの通っている箇所の色付けがおかしいのと網羅率に誤差があると感じてました。

よくよくgithubのrcovのページを見てみると、

NOTE: This fork does not work on Ruby 1.9.x. For coverage on Ruby 1.9 look at SimpleCov. Even if you get results on 1.9 they will probably be inaccurate. Ruby 1.9 has call detection built in for faster, more accurate results.

なんて書いてあります。という訳でSimpleCovを試してみました。

なおこちらで簡単にセットアップできるシェルスクリプト置いてます!

■説明

まずはいつものGemfileに

gem 'simplecov', :require => false

と記載して

$ bundle install

次にspec/spec_helper.rbに下記コードを追加しましょう。
この時大事なのは実行の早い段階(railsが読み込まれる前!)で下記を実行する必要がある事です。

require 'simplecov'
SimpleCov.start 'rails'



$ rake spec

すると、coverageディレクトリ以下にhtmlファイルが出力されます(画像はsimplecovのページより)


このままでも良いのですが、rcovのフォーマットと異なるので、CIに統合するには不便です。そんな時はsimplecov_rcovを利用すると上手く行きます。

group :test do
  gem 'simplecov', :require => false
  gem 'simplecov-rcov', :require => false
end

$ bundle install

spec/spec_helper.rbには、SimpleCovの出力フォーマットを変更するコードを書きます。

require 'simplecov'
require 'simplecov-rcov'
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter

※くれぐれも早い段階で読み込んで下さい!

すると見慣れたあのHTMLがcoverage/rcov以下に出力されます。
coverage/rcovをCI(というかjenkins)のrcovレポートの場所として指定してあげると良好な結果が得られます!

ちなみにsimplecov-rcovのページで下記の様な記載があり、網羅率測定有無を切り替える方法があります。
if( ENV['COVERAGE'] == 'on' )
  require 'simplecov'
  require 'simplecov-rcov'
  SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
  ...
end

$ COVERAGE=on rake spec
また複数の出力フォーマットで出力する例もありますので是非見てみて下さい。

2011年7月28日木曜日

railsでネストしたレイアウトを実現する

railsのviewはレイアウト機能があり、画面の共通化が可能です。

・画面のイメージ・レイアウトを共通化する
・メニューを表示する
...etc

非常に便利な機能ですが、「サイト全体で画面のイメージを共通化しつつ、XXX機能でも共通のレイアウトにする」事が簡単にはできないと思っていました(レイアウトの二重適用)。
ところがRuby on Rails Guidesに実現方法がのっていました。非常に簡単なのでご紹介しておきます。

■application.html.erb (全体的な共通レイアウト)

<html>
<head>
  <title><%= @page_title or 'Page Title' %></title>
  <%= stylesheet_link_tag 'layout' %>
  <style type="text/css"><%= yield :stylesheets %></style>
</head>
<body>
  <div id="top_menu">Top menu items here</div>
  <div id="menu">Menu items here</div>
  <div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
</body>
</html>
上記のポイントは二つ。

・yield :stylesheets
=> 機能側で定義したstylesheetをheadタグ内にレンダリングする例です
・content_for?(:content) ? yield(:content) : yield
=> 機能側で:contentがある場合は引数にしてyield、無い場合通常のyield

■news.html.erb(機能毎レイアウト)

<% content_for :stylesheets do %>
  #top_menu {display: none}
  #right_menu {float: right; background-color: yellow; color: black}
<% end %>
<% content_for :content do %>
  <div id="right_menu">Right menu items here</div>
  <%= yield(:news_content) or yield %>
<% end %>
<%= render :file => 'layouts/application' %>
・content_for :stylesheets
=>上記のstylesheetを準備します。同じようにjavascriptも定義可能です。
・content_for :content / yield(:news_content) or yield
=> :contentを定義し、更に:news_contentがある場合は引数にしてyield、無い場合通常のyield
・render :file => 'layouts/application'
=> 上記contentを準備して、全体レイアウトをレンダリング

■xxx.html.erb(各画面)

<h1>タイトル</h1>
...

各画面固有のレンダリング内容

■xxx_controller.rb

class XxxController < ApplicationController
   layout "news"
   def xxx
   end
end

layoutで機能毎共通レイアウトを指定
上記の様に設定すると
application.html.erb
  news.html.erb
    xxx.html.erb

とネストしたレンダリング可能です!

■備考

2011/07/21 22:06 なんてこったい! Rails3レシピブックにのっているじゃないか(^_^;)

2011年7月6日水曜日

rails on oracle (oracleで接続する手順) その2

■概要

rails on oracle でいくつかのテーマで検証してみます

●fetchループ

module FetchTest
  SQL = "select p1.* from posts p1 cross join posts p2"
  def self.run
    Post.delete_all
    200.times do |i|
      Post.create(:title => "title_#{i}", :body => "body_#{i}")
    end
    open("test.txt", "w") do |f|
      # ① Post.find_by_sql(SQL).each { |r| f.write "#{r}\r\n" }
      # ② Post.connection.raw_connection.exec(SQL) { |r| f.write "#{r}\r\n" }
    end
  end
end

FetchTest.run

上記の場合①は通常の検索処理。sqlの実行結果を全てメモリ上に展開します。
②の場合、fetchループで繰り返し処理が発生する為、"同時に必要となるメモリ"は少なくてすみます。

# それぞれ実行しながら、topコマンド等でメモリ利用状況を確認しましょう。

よって大量のcsv出力する場合は必ず②のようにする必要があります。

●DROP

railsで実装する場合、割と頻繁にDBスキーマの全削除、再作成をするかと思います(うちだけ?)。その際の機能は充実してきており、adapter内で多数のDROP文が実装されています。

但し適宜 purge recyclebin してあげないとゴミがたまりそうです。

●indexの表領域

性能向上の為、データ/インデックスを別HDDに保存する場合、データ/インデックスで表領域を分ける必要があります。oracle_enhanced_adapterは成長しており、migrationで

add_index :posts, :title, :tablespace => 'foo'

のように指定できます。

●varchar2問題

oracleのvarchar2/char2は歴史的な経緯で、"バイト単位"での長さ指定になります。
よってrailsからスキーマ作成する際は、string => nvarchar2へのマッピングを以前はしていたのですが、最近のoracle enhanced adapterは進化しています!

lib/active_record/connection_adapters/oracle_enhanced_adapter.rb によれば、nls_length_semantics というオプションがデフォルトで'CHAR'となっており、このオプションを指定する事によってvarchar2/char2を文字数単位で長さ指定出来る様になります。

よって何も考えなくても、mysql等と同じように指定できる様になりました。
実際下記の用にスキーマが出来ています。
SQL> desc posts;
 名前                     NULL?    型
 -------------------------- -------- ----------------------------
 ID                         NOT NULL NUMBER(38)
 TITLE                               VARCHAR2(255 CHAR) <= CHARで255
 BODY                                CLOB
 CREATED_AT                          DATE
 UPDATED_AT                          DATE
●oracle enhanced adapter独自項目の設定 oracle enhanced adapterには独自の設定項目があり...と思ったら良いページがありました。一部ソースを読んだ結果下記の様です。
# config/initializers/oracle.rb 等に下記内容を設置
ActiveSupport.on_load(:active_record) do
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
    # NUMBER(1)をbooleanにマッピングするか
    self.emulate_booleans = true
    # DATE型を(rubyの)Date型にマッピングするか
    self.emulate_dates = false
    # カラム名が(^|_)date(_|$)とマッチする場合Date型にマッピングするか
    self.emulate_dates_by_column_name = false
    # カラム名が(^|_)idとマッチする場合Integer型にマッピングするか
    self.emulate_integers_by_column_name = true
    # CHAR(1)かVARCHAR(1)、またはカラム名が_FLAG/_YNで終了する場合Booleanにマッピングするか
    self.emulate_booleans_from_strings = true
    # シーケンサー作成する際のオプションを指定する
    self.default_sequence_start_value = "1 NOCACHE INCREMENT BY 1"
  end
end
●雑感
ソース見て思ったのですが、oracle enhanced adapter マジで進化してます!
かなりきっちりしてる感じです(識別子30文字制限問題、in句の1000上限問題 ...etc)

2011年7月2日土曜日

履歴管理システムの無視ファイル

cvs/subversion/git等、色々な履歴管理システムがありますが、いずれも "履歴管理しないファイル" を適切に指定する事が大切です。

# *.classを無視していない為、すごい事になっているチーム結構みた事あります  (;´д`)トホホ…

いつも調べてる様な気がしたので、これを気にまとめようかなと調べたら

...

かなり良いの発見しました!

github/gitignore

githubのチームが作成しています。色々な言語・フレームワークのgitignoreファイルサンプルがたくさんあります。ちなみにRails.gitignore

*.rbc
*.sassc
.sass-cache
capybara-*.html
.rspec
/.bundle
/vendor/bundle
/log/*
/tmp/*
/db/*.sqlite3
/public/system/*
/coverage/
/spec/tmp/*
**.orig
config/*.yml
rerun.txt
pickle-email-*.html

のようですね。確かに一通りそろってる感じ!

■追記

2011/08/04 下記もいるような気がする
/spec/reports/

後上記の設定ならdatabase.ymlも消えるので、database.yml.example => database.ymlへのコピーが手順的に入りますね!

2011年6月28日火曜日

rails on oracle (oracleで接続する手順) その1

■概要

railsをoracleで接続したい人はあまり多くないと聞いた & 最近の情報があまり見当たらないので、ニッチな人向けに纏めておこうと思います。

■Oracle XEのインストール

まずはサーバ側。既に何らかのOracleが存在する場合はここはパスして下さい。

・http://www.oracle.com/technetwork/database/express-edition/downloads/102xelinsoft-102048.html
ここからoracle-xe-univ-10.2.0.1-1.0.i386.rpm をダウンロード

※アカウントが必要なので先に登録して下さい。
※今日(2011/06/28)調べたらOracle XE 11.2 betaなる文字が!!

・↑をインストール

$ sudo rpm -ivh oracle-xe-univ-10.2.0.1-1.0.i386.rpm
$ sudo /etc/init.d/oracle-xe configure

↓管理アプリのポートを聞かれてます。他とバッティングする場合は変えましょう(例 9080)。
Specify the HTTP port that will be used for Oracle Application Express [8080]:

↓Oracleの待ち受けポートです。通常はdefaultのままで良いでしょう。
Specify a port that will be used for the database listener [1521]:

↓SYSとSYSTEMのパスワードをきかれてるので適当な物にしましょう。
Specify a password to be used for database accounts. Note that the same
password will be used for SYS and SYSTEM. Oracle recommends the use of
different passwords for each database account. This can be done after
initial configuration:

↓OS起動時に起動するかと言われてるので、通常稼動環境ではyです。
Do you want Oracle Database 10g Express Edition to be started on boot (y/n) [y]:

・確認

$ sudo /etc/init.d/oracle-xe status

■Oracle Instance Clientのインストール

続いては接続側。できるだけ接続側は綺麗にしておきたいので、Oracle Instance Clientから接続しようと思います。

・http://www.oracle.com/technetwork/jp/topics/index-099943-ja.html より対応するバージョンをダウンロード
oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.rpm
oracle-instantclient11.2-devel-11.2.0.1.0-1.x86_64.rpm
oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.rpm
をダウンロードしてみました。

・↑をインストール

$ sudo rpm -ivh oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.rpm
$ sudo rpm -ivh oracle-instantclient11.2-devel-11.2.0.1.0-1.x86_64.rpm
$ sudo rpm -ivh oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.rpm

・環境変数に下記を設定

$ vim ~/.bash_profile
export LD_LIBRARY_PATH=/usr/lib/oracle/11.2/client64/lib/:$LD_LIBRARY_PATH
export NLS_LANG=JAPANESE_JAPAN.AL32UTF8
export PATH=/usr/lib/oracle/11.2/client64/bin/:$PATH

$ source ~/.bash_profile

・接続確認

$ sqlplus system/パスワード@サーバのIP:1521/XE

■railsから接続

・ruby-oci8のインストール

$ gem install ruby-oci8 -v2.0.6
(Oracle Instance Clientの場合は、LD_LIBRARY_PATHを設定しておけばコンパイルに支障が無いようです)

・rails試しに作成

$ rails new oracle_test -d oracle
$ cd oracle_test
$ vim Gemfile
ruby-oci8の辺りを↓のように記載
gem 'ruby-oci8', '~> 2.0.6'
# gem 'activerecord-oracle_enhanced-adapter', '~> 1.3.2'
gem 'activerecord-oracle_enhanced-adapter', '~> 1.3.2', :git => 'git://github.com/rsim/oracle-enhanced.git' (1.3.2以降にユーザー作成機能が追加されていますので以後はそれで実行しています)

$ bundle install
$ vim config/database.yml
development:
adapter: oracle_enhanced
database: //サーバのIP:1521/XE
username: kennyj_development
password: xxxxx

test:
adapter: oracle_enhanced
database: //サーバのIP:1521/XE
username: kennyj_test
password: xxxxx

production:
adapter: oracle_enhanced
database: //サーバのIP:1521/XE
username: kennyj_production
password: xxxxx

$ rake db:create:all (userまで作ってくれます!)
Please provide the SYSTEM password for your oracle installation
>xxxxx (development)
Please provide the SYSTEM password for your oracle installation
>xxxxx (test)
Please provide the SYSTEM password for your oracle installation
>xxxxx (production)

$ rails g scaffold Post title:string body:text (いつもの奴生成)
$ rake db:migrate
== CreatePosts: migrating ====================================================
-- create_table(:posts)
-> 0.0349s
== CreatePosts: migrated (0.0350s) ===========================================

$ rake test (test実行)

$ rails s
(ブラウザで確認)
http://localhost:3000/posts

■さらに使いやすく...

次回はもう少し濃い話題(fetchループ, nvarchar, 表領域, oracle_enhanced特有の初期設定...etc)を書ければと思います。

■雑感

oracle_enhanced異様に進化している気がする...

2011年6月16日木曜日

gemやmavenで気をつけるべき事

gem(ruby)や、maven(java)を利用し始めると、

「何て便利なんだ!」

と感じると思います。実際非常に便利です。

しかし何年にも渡って運用するようなシステムの場合、「ハード故障に伴うリプレース」や「インフラ移行」が発生する場合があります。
その際に絶対忘れてはいけないのは、

「ライブラリ提供側が、いつまでも場所を提供してくれると考えてはいけない」

という事です。

実際gemで起こった事があるのは、

・githubが提供場所では無くなった(gemcutterへ移行?)
・gems.rubyonrails.orgが提供場所では無くなった(gemcutterへ移行?)
・sqlserverのアダプターの特定のバージョン(1.0.0.9250)が取得できなくなった。
  現在は http://rubygems.org/gems/activerecord-sqlserver-adapter/ ですが欲しいバージョンがありません。

と、かなり慌ててしまう状況です。

# さらに性質が悪いのがmaven。
# 私が出くわしたのは「リポジトリはあるがライブラリの該当バージョンが提供されなく無くなった」状況。
# なんと「*.jarの中身をテキストエディタで見ると、503のHTML」。
# しかもエラーを出力しないという難しい状況になります(どのファイルが無くなったのか分からない)

よってgemの場合cacheディレクトリ以下のgemファイルはちゃんととっておきましょう!」というのが教訓になります。もちろんアプリ側ではversionを絶対指定しておく」というのも大事ですね。

もちろんrailsの場合、vendor配下にコミットしたら良いのでは?という意見もあるかもしれませんが、度々デプロイする場合、純粋にサイズが大きすぎて遅い場合があります。
コンテキストに合わせて最良の方法を考えましょう。

rails自体の開発環境を作る4(完結)

■概要

さくらvpsを再インストールし下記を目標に再構築した際の記録を残しておきます。

・サーバとして一般的に行う設定がなされている事
・最低限のサーバセキュリティを維持している事
・rails自体の開発出来る事
・node.js、coffeescriptが動く事

■パッケージ管理・導入(centos5.5 x86_64版 さくらvps)

●パッケージ最新化
# yum -y update

●当面必要そうなパッケージをインストール
# yum -y install vim-enhanced nmap curl

●webサーバ/DB系をインストール
# yum -y install httpd httpd-devel
# yum -y install sqlite sqlite-devel
# yum -y install mysql mysql-server mysql-devel
# yum -y install postgresql84 postgresql84-contrib postgresql84-devel postgresql84-libs postgresql84-server

●rpmforgeの設定を行う
# wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
# rpm -i rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
# rm rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
# vim /etc/yum.repos.d/rpmforge.repo
(8行目)
enabled = 1 から enabled = 0 に変更(デフォルトで動かないようにする)

●gitインストール
# yum -y install git --enablerepo=rpmforge

●memcachedインストール
# yum -y install libevent libevent-devel
(素直に依存パッケージが解決しないので手動でインストールする)
# wget http://packages.sw.be/perl-Net-SSLeay/perl-Net-SSLeay-1.36-1.el5.rfx.x86_64.rpm
# wget http://packages.sw.be/perl-Net-SSLeay/perl-Net-SSLeay-1.36-1.el5.rfx.i386.rpm
# wget http://packages.sw.be/perl-IO-Socket-SSL/perl-IO-Socket-SSL-1.34-1.el5.rfx.noarch.rpm
# rpm -Uvh perl-Net-SSLeay-1.36-1.el5.rfx.x86_64.rpm
# rpm -Uvh perl-Net-SSLeay-1.36-1.el5.rfx.i386.rpm
# rpm -Uvh perl-IO-Socket-SSL-1.34-1.el5.rfx.noarch.rpm
# rm *.rpm
# yum -y install memcached memcached-devel --enablerepo=rpmforge

参考 http://nakoruru.jp/?p=439

●その他開発用パッケージのインストール
# yum -y install openssl-devel curl-devel readline-devel zlib-devel
# yum -y install java
# yum -y install libxml2 libxml2-devel libxslt-devel
# yum -y install libyaml-devel libffi-devel --enablerepo=rpmforge

●sqlite3が古いので自分でインストール
# wget http://www.sqlite.org/sqlite-autoconf-3070603.tar.gz
# tar zxvf sqlite-autoconf-3070603.tar.gz
# cd sqlite-autoconf-3070603
# ./configure
# make
# make install

※yumでインストールした物と競合しているはず。
ただyumでの依存関係があるので、あえて競合してインストールしてみた。

■設定

●日本語化
# vim /etc/sysconfig/i18n
(1行目)
LANG="C" から LANG="ja_JP.UTF-8" に変更

●不要デーモンの停止設定
# chkconfig auditd off
# chkconfig autofs off
# chkconfig avahi-daemon off
# chkconfig bluetooth off
# chkconfig cups off
# chkconfig firstboot off
# chkconfig gpm off
# chkconfig haldaemon off
# chkconfig hidd off
# chkconfig kudzu off
# chkconfig lvm2-monitor off
# chkconfig mcstrans off
# chkconfig mdmonitor off
# chkconfig messagebus off
# chkconfig netfs off
# chkconfig nfslock off
# chkconfig pcscd off
# chkconfig portmap off
# chkconfig rawdevices off
# chkconfig restorecond off
# chkconfig rpcgssd off
# chkconfig rpcidmapd off
# chkconfig smartd off
# chkconfig xfs off
# chkconfig yum-updatesd off

参考 http://tanaka.sakura.ad.jp/archives/001065.html

●firewall設定
# system-config-securitylevel-tui
(firewallをenabledにし、22/80/443/3000/10022(後述)/8080(後述)を開けた)

●作業用ユーザ作成
# useradd kennyj
# passwd kennyj

●sudo設定
# /usr/sbin/visudo
(一番下に追記)
kennyj  ALL=(ALL)       ALL

●ssh設定
# vim /etc/ssh/sshd_config
(13行目)
#Port 22 => Port 10022 (22番は非常に攻撃されやすいので)
(39行目)
#PermitRootLogin yes => PermitRootLogin no
(59行目)
#PermitEmptyPasswords no => PermitEmptyPasswords no

# /etc/init.d/sshd restart

●firewall再設定
# vim /etc/sysconfig/iptables
(22番ポートを閉じる)

●時間同期設定(ntp)
(さくらVPSでは最初から設定されていました)
# yum -y install ntp
# vim /etc/ntp.conf
# ntpdate ntp.nict.jp (とりあえず一旦近づけておく)
# /etc/init.d/ntpd start
# chkconfig ntpd on

参考 http://centossrv.com/ntp.shtml

●postgresql準備
# service postgresql initdb

●mysql準備
# vim /etc/my.cnf
(文字列エンコーディングをUTF-8に設定)
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
old_passwords=1
default-character-set = utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
default-character-set = utf8

[mysql]
default-character-set = utf8

●必要に応じてサービス起動設定
# chkconfig httpd on
# chkconfig mysqld on
# chkconfig postgresql on
# chkconfig memcached on

●一旦再起動
# reboot

※これ以降はkennyjユーザで作業しています。

■javascript関係

●node.js/npm/coffeeスクリプトのインストール
$ wget http://nodejs.org/dist/node-v0.4.8.tar.gz
$ tar zxvf node-v0.4.8.tar.gz
$ cd node-v0.4.8
$ ./configure
$ make
$ sudo make install
$ cd ..
$ curl http://npmjs.org/install.sh > npm.sh
$ chmod a+x npm.sh
$ sudo PATH=/usr/local/bin:$PATH ./npm.sh
$ sudo PATH=/usr/local/bin:$PATH npm install -g coffee-script
$ rm npm.sh

■ruby関係

●rvmのインストール
$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
$ source ~/.bash_profile
$ rvm pkg install iconv
$ rvm install 1.9.2 --with-iconv-dir=$rvm_path/usr
$ rvm install ree   --with-iconv-dir=$rvm_path/usr
$ rvm install 1.8.7 --with-iconv-dir=$rvm_path/usr
$ rvm install jruby
$ rvm use --default 1.9.2

●railsインストール
$ rvm 1.8.7,1.9.2,ree,jruby gem install rails --no-rdoc --no-ri

※jruby1.6.1では落ちたので注意
  arel2.0.10がNG。jruby1.6.2では直っています
  http://jira.codehaus.org/browse/JRUBY-5581
  https://github.com/jruby/jruby/commit/dd1d9382a72af181e9d3998f2680154ebf1e651c

●sassのインストール
$ rvm 1.8.7,1.9.2,ree,jruby gem install sass --no-rdoc --no-ri

■rails自体の開発環境

●mysqlの設定
$ sudo /etc/init.d/mysqld start
$ mysql -u root
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*  to 'rails'@'localhost';
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost';

●postgresqlの設定
$ sudo /etc/init.d/postgresql start
$ sudo -u postgres createuser --superuser $USER

●gitの設定
$ git config --global user.name "kennyj"          # 名前
$ git config --global user.email kennyj@gmail.com # メールアドレス

●railsの取得とテスト
$ git clone git://github.com/rails/rails.git
$ cd rails
$ bundle install
$ cd activerecord
$ rake mysql:build_databases
$ rake postgresql:build_databases
$ cd ..
$ rake test

●railsを修正しパッチを作成する
$ git checkout -b xxxxx # ブランチ名
(ソース修正)
$ git commit -a -m "コミットメッセージ"
$ git checkout master
$ git pull
$ git checkout xxxxx
$ git rebase master
$ git commit -a
$ git format-patch master --stdout > xxxxx.diff
$ cat xxxxx.diff

■更新記録

2011/06/23 ntpについて追記
サービス起動設定について追記

2011/08/02 rvm package -> rvm pkgに変更

2011年5月22日日曜日

rails自体の開発環境を作る3

■概要

rails3をモジュール別にテストしていますが、activerecordだけはDBの準備があるので少し面倒そうです。

■activerecord

○sqlite3

$ cd activerecord
$ RUBYOPT=-W0 rake test_sqlite3

......
2986 tests, 9101 assertions, 0 failures, 0 errors, 2 skips

とくに問題なさそうだ。

○mysql & postgresql

まずはデータベースの準備

# yum install mysql mysql-devel mysql-server
# yum install postgresql84 postgresql84-contrib postgresql84-devel postgresql84-libs postgresql84-server

bundlerが、"DB無し設定"なので、再取得する。

$ rm .bundle/config
$ bundle install (adapterのコンパイルが成功するはず)

mysqlの下準備は、ユーザの権限付与とDB構築

# /etc/init.d/mysqld start
$ mysql -u root
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.* to 'rails'@'localhost';
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost';
$ cd activerecord
$ rake mysql:build_databases

postgresqlの下準備は、DB作成とユーザ周り

# service postgresql initdb
# /etc/init.d/postgresql start
$ sudo -u postgres createuser --superuser $USER
$ cd activerecord
$ rake postgresql:build_databases

で、テストを実行

$ RUBYOPT=-W0 rake test
......
2977 tests, 9114 assertions, 0 failures, 0 errors, 2 skips

お、動いた!!(postgresqlで2つ程落ちてますが。。)

■次回予告

ここまでの作業を纏めて、目指せコントリビュータ!な感じにしようと思います。