Hatena::ブログ(Diary)

130単位

2011-06-29

今現在のエンジニアとしての自分についてプレゼンしました

本日が最終出社日でした。

そのような区切りの意味もあって、社内勉強会で発表をする機会をいただきました。せっかくなので、これまでとこれからの自分についてしゃべってみました。それが今の自分の立場/状況で、最も伝えるべきことではないかと感じたからです。

no title

f:id:deeeki:20110629051554p:image:w320

アジェンダ

  • わたしのルーツ
  • わたしのおすすめ
  • わたしの考え

わたしのルーツ

中学時代から現在までの振り返りです。

中学時代

休み時間には友人と将棋、家ではドラクエFFを遊んでました。ひねくれていたため、人と違うことをしてみたいという思いを常に持っていた気がします。

高校時代

電話機の関係でたまたま自分の部屋に置かれることになったWindows98のパソコンで、初めてインターネットに触れました。友人のホームページがWeb上でそれなりに存在感を出していて、少し憧れを持ちました。受験年度にオンラインゲームAoK(AoC)にのめり込み、毎日テレホタイムが楽しみでしかたありませんでした。

大学時代前半

人見知りと大きな環境の変化が絶妙ブレンドされた結果、ひきこもりになりました。ウイイレにハマって海外サッカーばかり観てました。あとは週2日のバイトとネットという非生産的な閉じた生活でした。

大学時代後半

改心のきっかけは、ほどよい距離感で接してくれたある大学職員の方と友人の存在でした。真剣10代しゃべり場という若者が討論するNHKの番組の、青臭くも熱い雰囲気がリハビリ中の身にはなぜか心地よかったです。その出演者がやってたブログに興味を持ち、自分もはじめてみました。なんとかたどり着いたプログラミングのバイトでVB6とSQLの実務経験を得ました。

大学時代終盤

研究室でPHPに触れました。卒業研究のアウトプットの場としてはてなダイアリーを始めました。Web系ベンチャーに足を踏み入れることにしました。

名古屋ベンチャー前半

入社前にバイトしてたものの、いきなり先輩1人と他社出向という無茶ぶりでした。定時後と土曜も開発し、JavaScriptを扱えるようになりました。OSC名古屋に参加し、オープンソース界隈の活動を初体験しました。

エンジニアの未来サミット

アルファギークな方たちのパネルディスカッションを生で観て、大きな衝撃を受けました。いつかは東京へ、と思い始めたのもこのときでした。

勉強会初参加

せっかくの東京というタイミングもあり前日に申し込んで、当日サイ本を購入して参加しました。懇親会ではデュアルディスプレイとかVimEmacsどっち派とかエンジニアなら当然の話題についていく知識も経験も当時はなく、苦々しい経験とともに外を意識するきっかけになりました。

名古屋ベンチャー後半

初のJava案件は自分の力不足もありかなりしんどいものでした。SAStrutsには大いに助けられました。WordPressのソースを追いまくりいじりまくりました。不況で仕事と収入に影響が出て、転職を考えはじめました。

東京
  • ブログ効用
  • 上司(面接官)と先輩と食事
  • 何喋ってるか全然わからなかった

ブログを書いていたおかげで、2年未満の経験ではふつう書類で落とされるところを数社通していただけたりしました(と思っています)。現職は3度目の面談のあとの食事の席で、上司と先輩のインフラ関連の会話に全くついていけなく、吸収しがいがありそうというのとタイミングで入社を決めました。

印象深い仕事

手がけたソーシャルアプリをGW前にリリースして、帰省中にイベントが無事に動いてほっと一息ついたりしました。47都道府県ブログは、これまでのWordPressの知識を存分に活用して効率的に構築できました。RailsアプリRuby/Vim/Gitを一挙に覚えられた非常にやりがいのある案件でした。

赤坂ベンチャー
  • やりたいことをやらせてもらえた
  • 世界を意識できた
  • たくさんの魅力的な人たちと働けた

引き継ぎ案件よりも、新規開発に多く携われたのは大変ありがたいことでした。海外のエンジニアSkypeでやりとりして、世界に目を向けるきっかけも得ました。活気があって個性的な方が多く、特に優秀な若者との出会いは刺激になりました。

わたしのおすすめ

自分に大きな影響を与えてきたサイト、書籍、動画などです。

おすすめサイト

RSS含めあらゆる記事の一次ソースとして、おそらく最も時間を使っているサイトです。

おすすめサイト

ロールモデルにしたい人のひとりで、よくTwitterURL紹介するのはここの影響だったりします。

おすすめサイト

ゆるいつながりと興味からの新たな出会いなど、ここのおかげでかなり人見知りが解消された気がします。

おすすめ動画

D

このプレゼンの元ネタだったりします。見返すたびに奮い立たされます。

おすすめ書籍

4480063870

この本が大きなきっかけとなってはてなダイアリーを始めました。またWeb系ベンチャーへ就職する後押しにもなりました。(若気の至り記事:111単位 長期戦を意識すること)

おすすめサイト

今や全国で毎週あらゆる勉強会が開催されています。最初の一歩を踏み出してみましょう。

おすすめ動画
  • プログラマが知るべき、たったひとつの大事なことがら』(和田卓人氏)
    • デブサミ2011 (2011-02-18) / 縦サミ2011 (2011-04-23)

D

芯のある落ち着いた語り口が印象的でした。

おすすめサイト
  • 新卒準備カレンダー2011』

新卒ITエンジニア向けの記事のリレー、一読おすすめします。

わたしの考え

普段意識していることと、今後についてです。

好きなこと
  • 新しいこと
  • 表現すること
  • 人のハブになること

上2つはまさにWebの世界でした。人見知りだからこそ、自分を介して新たなつながりの手助けができたら幸いです。

得意なこと
  • 情報収集
  • 手順化
  • コードの整理

1つめはネットサーフィンを、2つめはブログを続けていて気づいたという感じです。3つめは、完璧主義が影響して他の人よりはできるような気がしています。

仕事で大切にしていること
  • 情報やノウハウの共有
  • 自ら学ぶ姿勢
  • 社内政治よりも目の前の成果

仕事でしっかり結果を出せば、自然と評価はついてくるものと思っています。自ら積極的に学んでそれを共有して、組織の向上に努めたいです。

個人で大切にしていること
  • アウトプット
  • 多くの人に覚えてもらうこと
  • どこでも働けるように

自分が幸せになるため(≒信頼関係とお金を得るため)には、これらが必要かと思っています。

開発環境のポリシー

キーボード等のハードからサーバー内のソフトまで、デフォルト状態を好みます。そのほうが他人との共有がスムーズにいくと思うからです。以前はWindowsオンリーでしたが、MacLinuxを使うようになって共通部分や違いを意識するようになり、転用/移植のしやすさを考えるようになりました。

設計/コードのポリシー
  • シンプルさ
  • 命名をまじめに考える
  • 可読性(統一感)

シンプルな設計を目指します。何に対してもですが、一般的かつ正しいやり方は何かを考えます。コーディングスタイルや命名の統一感はかなり気にします。またチーム開発の場合は書いた相手の意図を読み取ることも大切と思います。

学びかた

RSSはてブのタグで絞り込んだものやエンジニアブログなどです。玉石混交気にせず、興味のあるトピックには毎日触れるようにします。まとまった知識を得るには本が一番です。トライ&エラーで経験を積んで体で覚えます。勉強会では人と会う/話すのと、外の世界で自分のポジションを客観視できます。

教えかた
  • 本人にやらせてわからないところだけ教える
  • 書籍を自ら買って読んでもらう
  • ブログを書いてもらう

放任ととらえられそうですが、結局のところ自分がやってることを真似してくださいとしか言えなかったりします。できる限りレビューやフィードバックはするつもりです。何人か接してきて思うのは、センスや才能も少しは影響してるかもしれませんが、自ら学ぶ姿勢が一番大切なんじゃないでしょうか。

これから学びたいこと

RubyPHPと同等以上には扱えるようになりたいです。スマホは個人で勝負できる可能性があるため。TDD/BDDプログラマの必須スキルであるため。英語は世界を広げるために。

これからやりたいこと

サービスは会社個人問いませんが、企画から運用までフルコミットしてみたいものです。人見知り非コミュは相変わらずですが、いろいろなエンジニアさんといろいろなお話ができるよう、日々精進です。そして何年後かに自信が持てるようになってから、若いエンジニアさんの成長の手助けができたらと思います。

さいごに

お伝えしたいこと
  • 発信しましょう
  • 共有しましょう
  • 挑戦しましょう

自分自身、これらをすることで自分/社会/世界がより良い方向に進むと思っています。少しでも共感していただけそうなら、ぜひいっしょにやってみませんか!


長い記事をお読みいただきありがとうございました。

そしてこれからもどうぞよろしくお願いします!


プレゼンツール

関連記事

2011-06-26

Google Analyticsデータ取得gemライブラリ「Garb」

Google AnalyticsData Export APIラッパーライブラリです。

環境

OAuthアクセストークン取得

ユーザー名とパスワードでも扱えますが、あえて茨の道を選択してみました。

Consumer Key,Consumer Secret取得
アクセストークン取得
require 'oauth'
CONSUMER_KEY = 'XXX'
CONSUMER_SECRET = 'XXX'

consumer = OAuth::Consumer.new CONSUMER_KEY, CONSUMER_SECRET, {
	:signature_method   => 'HMAC-SHA1',
	:site               => 'https://www.google.com',
	:request_token_path => '/accounts/OAuthGetRequestToken',
	:authorize_path     => '/accounts/OAuthAuthorizeToken',
	:access_token_path  => '/accounts/OAuthGetAccessToken',
}

request_token = consumer.
	get_request_token({}, :scope => "https://www.google.com/analytics/feeds/")

print request_token.authorize_url + "\n"
ACCESS_CODE = STDIN.gets.gsub!(/\n/,'')

access_token = request_token.get_access_token(:oauth_verifier => ACCESS_CODE)

print "ACCESS_TOKEN = '" + access_token.token + "'\n"
print "ACCESS_SECRET = '" + access_token.secret + "'\n"
  • authorize_urlとget_access_tokenはrequest_tokenが同一インスタンスでないといけないっぽい
  • irbでやってもよかったかもしれない

Analyticsデータ取得

require 'garb'
ACCESS_TOKEN = 'XXX'
ACCESS_SECRET = 'XXX'

#consumer生成までは上記コードと同じ
access_token = OAuth::AccessToken.new(consumer, ACCESS_TOKEN, ACCESS_SECRET)

Garb::Session.access_token = access_token
profile = Garb::Management::Profile.all.detect {|p| p.web_property_id == 'UA-XXXXXXX-X'}

class PageTitle
	extend Garb::Model

	metrics :pageviews
	dimensions :hostname, :page_path, :page_title
end

rs = PageTitle.results(profile, {:limit => 20, :sort => :pageviews.desc})
rs.each do |r|
	print r.pageviews + "\n" + r.page_title + "\n" + r.hostname + r.page_path + "\n\n"
end

サンプル

こちらに一連の手順のサンプルコードが置いてあります。READMEなくてわかりづらいかもしれませんが、試してみたい方はどうぞー。


4873113946
プログラミング言語 Ruby

4839935483
Google Analyticsではじめるテストマーケティング

*1:動的に値を追加変更できる構造体、バリューオブジェクト的なもの

2011-06-25

Rails3 失敗から学ぶDevise利用時のURL設計

要件

  • ユーザー登録のあるアプリ
  • メアドで仮登録→本登録で各情報入力
    • 仮登録状態の時は本登録に強制遷移
  • 新規登録とは別にマイページが存在
  • ユーザーのプロフィール入力とアプリ設定入力は別画面
  • 新規登録では確認画面や完了画面もほしい
    • マイページでの編集時はなしにした

やや複雑な仕様のため一般化するのは難しいかもしれませんが、自分が選択したやり方を紹介してみます。

環境

  • Rails3.0.7
  • Devise1.3.4

モデル設計

  • User
    • UserProfile
    • UserSetting
  • UserはDevise用フィールドのみにして、プロフィール等は関連モデルで定義

当初のURL設計(失敗例)

#新規登録
match 'register/profile'
match 'register/setting'
post  'register/confirm'
post  'register/create'
get   'register/complete'

#マイページ
get   'my' => 'my#index', :as => :my_root
get   'my/profile_edit'
post  'my/profile_update'
get   'my/setting_edit'
post  'my/setting_update'

#Devise 認証系
devise_for :users, :controllers => { :registrations => 'users/registrations' }, :skip => [ :registrations ] do
  get   'users/sign_up' => 'users/registrations#new', :as => :new_user_registration
  post  'users' => 'users/registrations#create', :as => :user_registration
  put   'users' => 'users/registrations#update', :as => nil
  delete  'users' => 'users/registrations#destroy', :as => nil
  get   'users/sign_up_complete' => 'users/registrations#sign_up_complete', :as => :complete_user_registration
  get   'my/authentication_edit' => 'users/registrations#edit', :as => :edit_user_registration
end
  • ユースケース(URL上の文字列)を第一優先してみた
    • 新規登録とマイページを明確に分けるため
  • Deviseの持つURLとの相性が悪い
    • 認証系のURLは'users'を利用していて統一感がない
  • 仮登録時や更新時のリダイレクト先変更のために自前Controllerを設ける必要がでてきた
  • Devise管理下であるメアド変更画面をマイページで扱おうとした
    • my/authentication_editという苦し紛れなURLになった
    • 'my'に変更するためにわざわざskipしてマッピングし直しているのが微妙すぎる

改良したURL設計

#新規登録
match 'user_entry/profile'
match 'user_entry/setting'
post  'user_entry/confirm'
post  'user_entry/create'
get   'user_entry/complete'

#マイページ
get   'user' => 'user#index'
get   'user/profile_edit'
post  'user/profile_update'
get   'user/setting_edit'
post  'user/setting_update'

#Devise 認証系
devise_for :users, :path => 'user', :controllers => {
  :confirmations => 'user/confirmations',
  :passwords => 'user/passwords',
  :registrations => 'user/registrations',
  :sessions => 'user/sessions',
  :unlocks => 'user/unlocks',
} do
  get   'user/sign_up_complete' => 'user/registrations#sign_up_complete', :as => :complete_user_registration
end
  • リソースを第一優先してRESTfulっぽくしてみた
  • 他ページとの兼ね合いで'user'は単数形にした
  • Deviseの認証系画面とマイページの画面がともに'user'になったことですっきりした
  • 新規登録のほうは名詞でuserと、Deviseの'registration'と区別するために'entry'という単語を用いた
    • Controllerを分けたのは、仮登録状態の強制遷移をController名で簡略化したかったため
  • 前述の通り完了画面遷移の実現は継承した自前Controllerにする必要がある
  • Viewのディレクトリがdeviseとuserで分かれるのを避けるため、中身空のものも含め全て自前Controllerに継承させた
  • Controllerの構成
    • user/*_controller … Devise 認証系
    • user_controller …マイページ
    • user_entry_controller … 新規登録

まとめ

  • Devise利用時、マイページとかのURLはusers(user)にするといいと思う
  • 再編集できるなら確認画面はいらない
  • Railsの流儀に乗っかると開発がスムーズ

【追記】resourceを使ったコンパクトなルーティングの書き方をコメントいただきました。感謝!

4774146633
Ruby on Rails 3 アプリケーションプログラミング

関連記事

2011-06-23

lsyncd2系で複数サーバーにリアルタイム同期

同期元でファイルの変更を検知してリアルタイムミラーリングできます。2.0系から設定ファイルがXMLでなくLUAという言語のものになったようです。

環境

構成

同期先サーバー

rsyncdで待ち受け
  • rsyncd設定
sudo vim /etc/rsyncd.conf
[application]
path = /path/to/application
log file = /tmp/rsyncd.log
uid = apache
gid = apache
read only = no
  • rsyncd起動
sudo rsync --daemon
rsyncd自動起動
sudo yum install xinetd
sudo vim /etc/xinetd.d/rsync
service rsync
{
        disable = no
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}
  • disableをnoにする
  • xinetdによる起動
sudo /etc/init.d/xinetd start
sudo chkconfig xinetd on

同期元サーバー

lsyncdインストール
#必要なパッケージ
sudo yum install make gcc pkgconfig lua-devel
#lsyncd DL&展開
wget http://lsyncd.googlecode.com/files/lsyncd-2.0.4.tar.gz
tar xzf lsyncd-2.0.4.tar.gz
#インストール
cd lsyncd-2.0.4
./configure
make && sudo make install
lsyncd設定
sudo vim /etc/lsyncd.conf
settings = {
   logfile    = "/tmp/lsyncd.log", --ログファイル
   statusFile = "/tmp/lsyncd.status", --同期ファイル状態
   nodaemon   = false, --デーモンモードON/OFF
}

sync {
    default.rsync, --同期コマンド種別
    source="/path/to/source", --同期元
    target="xxx.xxx.xxx.xxx::application", --同期先
    rsyncOps="-ltus" --rsync上書きオプション
}

--[[
sync {
    default.rsync,
    source="/path/to/source",
    target="xxx.xxx.xxx.xxx::application",
    rsyncOps="-ltus"
}
]]
  • settingsに設定記述
  • syncに同期の情報記述
  • defalut.rsyncの動作
/usr/bin/rsync -ltsd --delete --include-from=- --exclude=* SOURCE TARGET
lsyncd起動
#動作チェック
lsyncd -rsync /path/to/source xxx.xxx.xxx.xxx::destmodule
#通常起動
lsyncd /etc/lsyncd.conf

使ってみて

  • ファイル変更から同期開始までは数秒の遅延がある
  • Webサーバー追加時は設定追記してlsyncd再起動必要
  • Webサーバーキャッシュクリアしたい場合
  • オートスケーリングとの共存は相当困難な気がする
    • オートスケーリング前提なら管理サーバーでrsyncd動かしてWeb側の初期スクリプトで取りにいくのが良さげ

関連リンク


4774145017
プロのための Linuxシステム構築・運用技術 (Software Design plus)

4774146005
サーバ/インフラエンジニア養成読本 [現場で役立つ知恵と知識が満載!] (Software Design plus)

関連記事

2011-06-21

AWS EC2 EBSインスタンス起動/停止用シェルスクリプト

EC2インスタンス(EBSタイプ)を開発用に利用していて、ほとんど触ることのない業務時間外も起動していることがちょっと無駄に思えてきました。そこでシェルから起動/停止できて、さらにcronに登録して自動化できないかと思ってつくってみました。

検証環境

シェルスクリプト

#!/bin/sh
case $1 in
	start)
		CMD=ec2-start-instances
		;;
	stop)
		CMD=ec2-stop-instances
		;;
	*)
		echo "Usage: sh manage_instances.sh [start|stop]"
		exit 1
esac

export JAVA_HOME="/usr/lib/jvm/jre"
export EC2_HOME="/opt/aws/apitools/ec2"
export PATH=/opt/aws/bin:$PATH
export EC2_CERT=$HOME/aws/cert-XXXXX.pem
export EC2_PRIVATE_KEY=$HOME/aws/pk-XXXXX.pem
export EC2_URL=https://ec2.ap-northeast-1.amazonaws.com
export EC2_REGION=ap-northeast-1
DESC_CMD="ec2-describe-instances -F group-name=staging"

for i in `$DESC_CMD | grep INSTANCE | cut -f2`
do
	INSTANCE=$i
	echo "***$1 $INSTANCE"
	$CMD $INSTANCE
done

つかいかた

30 9 * * 1-5 /path/to/manage_instances.sh start #平日9時半に全て起動
30 21 * * 1-5 /path/to/manage_instances.sh stop #平日21時半に全て停止

Elastic IP 割り当て

上記で起動停止はできますが、起動の度にIPが毎回変わってしまうのがネックです。そこでベタ書きにはなってしまうのですが、IP割り当ても自動化するには以下をループの中に記述します。(インスタンスID、Elastic IPとも使える状態のものを記述)

if [ $1 = start ]; then
        case $INSTANCE in
                i-xxxxx)
                        IP=xxx.xxx.xxx.xxx
                        ;;
                i-yyyyy)
                        IP=yyy.yyy.yyy.yyy
                        ;;
        esac
        echo "***associate $IP"
        ec2-associate-address -i $INSTANCE $IP
fi

これで多少のコスト削減につながればなーと思います。


4774142840
よくわかるAmazonEC2/S3入門 ―AmazonWebServicesクラウド活用と実践 (Software Design plusシリーズ)

4844329804
Amazon Web Services ガイドブック クラウドでWebサービスを作ろう!

関連記事

2011-06-20

Rubyで短縮URLのハッシュ値的なものの実装例

要件

  • できるだけ短く
  • 一意性の保証

環境

モデル例

class Page
  include Mongoid::Document
  include Mongoid::Timestamps

  field :url, type: String
  field :key, type: String #ハッシュ値
end

初期実装

before_create :generate_key
validates :user_id, :presence => true, :uniqueness => true

def generate_key
  chars = [('0'..'9'),('a'..'z'),('A'..'Z')].map{|c| c.to_a }.flatten
  i = Time.now.to_i
  digit = []
  begin
    i, c = i.divmod chars.length
    digit << chars[c]
  end while i > 0
  self.key = digit.reverse.join
end

一意性が欠落している不完全な実装でした。まねしないでください。

改良版

before_validation :generate_key
validates :user_id, :presence => true, :uniqueness => true
validates :key, :presence => true, :uniqueness => true

def generate_key
  return if self.key.present?
  chars = [('0'..'9'),('a'..'z'),('A'..'Z')].map{|c| c.to_a }.flatten
  begin
    key = (0..6).map{ chars[rand(chars.length)] }.join
  end until Page.where(:key => key).blank?
  self.key = key
end
  • バリデーション前にハッシュ値生成
    • 本来のvalidatesが記述できた
  • 6文字でランダムにハッシュ値生成
    • 既に存在したら再生成
  • saveの度にgenerate_keyが呼ばれるのは仕方ないところか

Thanks [twitter:@yuki24] !

その他

  • MySQLは大文字小文字区別しないので型をbinaryにする必要がある
  • MongoDBは大文字小文字区別するので問題なし

もっと良い実装があったら教えてくださいー。

関連リンク

4797359986
Rubyレシピブック 第3版 303の技

2011-06-16

Rails3 url_forのtrailing_slashを常に有効化とその影響

きっかけ

  • ルーティングで:namespaceを使って分けたサブアプリ
  • url_forでスラッシュで終わらないのが若干気になる
  • 都度オプション書くのは面倒なのでできたら一括で対応したい

で、ついでにurl_forの指定によって出力がどのように変わるか調べてみました。

環境

  • Rails3.0.8
  • Pow0.3.1

導入

rails new railsapp && cd railsapp
rails g scaffold pages
rails g scaffold subapp/pages
rake db:migrate
rm public/index.html

config/routes.rb

Railsapp::Application.routes.draw do
  namespace :subapp do
    resources :pages
    root :to => 'pages#index'
  end
  resources :pages
  root :to => 'pages#index'
end

実験

app/views/index.html.erb

<%= url_for '/' %><br />
<%= url_for :root %><br />
<%= root_path %><br />
<%= root_url %><br />
<%= root_path :k => 'v' %><br />
<%= root_url :k => 'v' %><br />
<%= page_path 1 %><br />
<%= page_url 1 %><br />
<%= page_path 1, :k => 'v' %><br />
<%= page_url 1, :k => 'v' %><br />
<%= url_for :subapp_root %><br />
<%= subapp_root_path %><br />
<%= subapp_root_url %><br />
<%= subapp_page_path 1 %><br />
<%= subapp_page_url 1 %><br />
<%= subapp_page_path 1, :k => 'v' %><br />
<%= subapp_page_url 1, :k => 'v' %><br />
デフォルト(trailing_slashなし)

f:id:deeeki:20110616012124p:image

trailing_slash常に有効化の記述

config/application.rb

config.action_controller.default_url_options = { :trailing_slash => true }

※Powならtouch tmp/restart.txtしてアプリ再起動必要

trailing_slashあり

f:id:deeeki:20110616012125p:image

わかったこと

  • 一括で対応するにはconfig.action_controller.default_url_optionsを利用する
  • rootのパスがおかしくなる
    • '/'と指定すれば問題ない
  • idなどパラメータもスラッシュありになる

actionpack-3.0.8/lib/action_view/helpers/url_helper.rb

# * :trailing_slash - If true, adds a trailing slash, as in "/archive/2005/". Note that this

# is currently not recommended since it breaks caching.

キャッシュがおかしくなるという注意書きがあります。アクションキャッシュで少し実験してみた感じでは問題ありませんでした。

まとめ



4774146633
Ruby on Rails 3 アプリケーションプログラミング

関連記事

2011-06-09

Rails2アプリをRails3.0系にアップグレード

Rails2のアプリをRails3にアップグレードしました。テストが無いと大変と聞いていましたが、便利なプラグインのおかげで意外とスムーズにできた気がします。

対象アプリ

以下の構成にします。

参考リンク

ASCIIcasts(Railscasts)の手順に沿えばほぼ問題なくいけるかと思います。

以下、細かいことも含め自分がやった作業のメモです。

準備

アップグレードプラグインインストール
rvm system #またはrvm 1.8.7
script/plugin install git://github.com/rails/rails_upgrade.git
アップグレード準備
rake rails:upgrade:check #Deprecatedなどチェックして対象ファイル一覧を標準出力
rake rails:upgrade:backup #主要ファイルをバックアップ

Rails3化

rvm 1.9.2
gem install rails
rails new .

基本的には rake rails:upgrade:check で出るものがなくなるように修正しつつ、動作確認していきます。またdevelopmentモードのWEBrickのログにも「DEPRECATION WARNING」と出るので修正していきます。

Deprecated対応

ActiveRecord周り

Soon-to-be-deprecated ActiveRecord calls

Methods such as find(:all), find(:first), finds with conditions, and the :joins option will soon be deprecated.

More information: http://m.onkey.org/2010/1/22/active-record-query-interface

  • where() をつかう

named_scope is now just scope

The named_scope method has been renamed to just scope.

More information: http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914

Updated syntax for validate_on_* methods

Validate-on-callback methods (validate_on_create/validate_on_destroy) have been changed to validate :x, :on => :create

More information: https://rails.lighthouseapp.com/projects/8994/tickets/3880-validate_on_create-and-validate_on_update-no-longer-seem-to-exist

View周り

Deprecated ERb helper calls

Block helpers that use concat (e.g., form_for) should use <%= instead of <%. The current form will continue to work for now, but you will get deprecation warnings since this form will go away in the future.

More information: http://weblog.rubyonrails.org/

  • form_forにイコール追加
find app/views/ -type f | xargs sed -i 's/<% form/<%= form/g'
find app/views/ -type f | xargs sed -i 's/ h / /g'

ActionMailer

Deprecated ActionMailer API

You're using the old ActionMailer API to send e-mails in a controller, model, or observer.

More information: http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3

プラグイン

Restful Authentication
rm -rf vendor/plugins/restful_authentication
rails plugin install git://github.com/Satish/restful-authentication.git restful_authentication
Paperclip
port install imagemagick #Mac
yum install ImageMagick-devel #RedHat
apt-get install libmagickwand-dev #Debian
  • Gemfileに追記して bundle install
gem 'rmagick'
gem 'paperclip'

その他

  • config/initializers/new_rails_defaults.rb削除
  • database.yml編集
    • adapterをmysqlからmysql2に変更
  • 日本語を利用しているrbファイルにマジックコメント追加
    • 一括置換(MacだとうまくいかなかったのでLinuxでやった)
find app/controllers app/models app/helpers -name "*.rb" | xargs sed -i '1s/^/# coding: utf-8\n/'
  • サブディレクトリ以下への柔軟なルーティング(※非推奨、アクションごとに明示したほうがよい)
match ':controller(/:action(/:id))', :controller => /subdir\/[^\/]+/
#return NKF.nkf('-U -s ' , str).gsub(/\n/,"\n\r").gsub(",",":")
return str.to_s.encode("sjis", "utf-8").gsub(/\n/,"\n\r").gsub(",",":")
#CSV::Writer.generate(output = "") do | csv |
CSV.generate(output = "") do | csv |

アップグレードプラグイン削除

rails plugin remove rails_upgrade

4774146633
Ruby on Rails 3 アプリケーションプログラミング

関連記事

2011-06-06

AWS RDS パラメータグループでMySQLの文字コードをUTF-8に設定

RDSはAWSのサービスのひとつで、RDBMSを手軽に利用出来るものです。簡単に用意できる代わりに、細かなカスタマイズには不向きだったりします。

以下、パラメータグループという仕組みをつかって、デフォルト文字コードUTF-8にする手順のメモです。

CUIツールセットアップ

設定値はWebから変更することができず、CUIのツールを用意する必要があります。

ダウンロード
設置例
$HOME
└── aws
    ├── RDSCli-1.4.006
    ├── cert-XXX.pem
    └── pk-XXX.pem
  • ホームディレクトリaws以下に設置
  • cert と pk は Acount > Security Credentials の X506Certificate から取得
    • アカウントを扱う場合はもう少し整理するといいでしょう

.bashrc

export JAVA_HOME=/Library/Java/Home
export AWS_RDS_HOME=$HOME/aws/RDSCli-1.4.006
export PATH=$AWS_RDS_HOME/bin:$PATH
export EC2_CERT=$HOME/aws/cert-XXX.pem
export EC2_PRIVATE_KEY=$HOME/aws/pk-XXX.pem
export EC2_URL=https://ec2.ap-northeast-1.amazonaws.com
export EC2_REGION=ap-northeast-1
  • JAVA_HOME変数の設定
  • AWS_RDS_HOME変数の設定
  • RDSツールにパスを通す
  • 各種EC2_XXX変数を設定しておくとコマンドで都度指定しなくて済む

使いかた

パラメータグループの値更新
rds-modify-db-parameter-group production -p "name=character_set_client, value=utf8, method=immediate"
rds-modify-db-parameter-group production -p "name=character_set_connection, value=utf8, method=immediate"
rds-modify-db-parameter-group production -p "name=character_set_database, value=utf8, method=immediate"
rds-modify-db-parameter-group production -p "name=character_set_results, value=utf8, method=immediate"
rds-modify-db-parameter-group production -p "name=character_set_server, value=utf8, method=immediate"
  • Web ConsoleでproductionというNameのパラメータグループを作成しておく
  • rds-modify-db-parameter-group を使う
  • とりあえず上記を実行すれば日本語を扱う文字コードの最低限の設定はokかと思います
    • character_set_filesystemはbinaryのままでもよい
インスタンス作成
  • 作成時に先程のproductionパラメータグループを指定すると、設定値が反映されます
MySQL接続
mysql --default-character-set=utf8 -u username -h production.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -p dbname
  • RDSのホスト名を-hで指定する
  • --default-character-set=utf8を指定する
  • dbnameを指定すると最初から扱うデータベースがセットされる
設定値確認
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

4844329804
Amazon Web Services ガイドブック クラウドでWebサービスを作ろう!

4774142948
エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

関連記事

2011-06-05

Amazon Linux RVM/Ruby1.9/Apache2/Passenger3環境構築

環境

Rails3.0.7を動かすサーバーを想定して、割と汎用的なAMIの作成を目指します。

各種パッケージ

以下rootユーザーにスイッチしての作業手順です(sudoだとRVMインストール時につまづきました)。

sudo su -
#アップデート
yum -y update

#Git
yum -y install git

#for Passenger
yum -y install gcc-c++ curl-devel openssl-devel zlib-devel httpd-devel apr-devel

#for RVM
yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel
yum install -y make bzip2
  • rvm notes で以下のように書いてあるのですがパッケージが存在しません

yum install -y iconv-devel # NOTE: For centos 5.4 final iconv-devel might not be available :(

Apache(+SSLモジュール)

yum -y install httpd
yum -y install mod_ssl
chkconfig httpd on
  • /etc/httpd/conf/http.confのNameVirtualHost *:80を有効化
  • /etc/httpd/conf.d/ssl.confのVirtualHostディレクティブをコメントアウト

RVM

bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
echo '[[ -s "/usr/local/rvm/scripts/rvm" ]] && . "/usr/local/rvm/scripts/rvm" # Load RVM function' >> /etc/bashrc
source /etc/bashrc

Ruby

rvm install 1.9.2
rvm use 1.9.2 --default

Passenger

gem install passenger --no-ri --no-rdoc
rvmsudo passenger-install-apache2-module
  • 依存関係で最新版のRakeインストールされる
    • Rails側で0.9未満を条件にしているなら事前にRake0.8.7を入れておくといいかも*1
vim /etc/httpd/conf.d/passenger.conf
LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7
PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p180/ruby

Bundler

gem install bundler --no-ri --no-rdoc

タイムゾーン

ln -sf /usr/share/zoneinfo/Japan /etc/localtime
ntpdate ntp.bbtec.net
  • 日本にして時刻合わせ

以上で、一度再起動してchkconfigの自動起動を確認したのち、不要なログを削除してAMI作成するといいと思います。


おまけ

for MySQL
yum -y install mysql-devel
for RMagick (Paperclip)
yum -y install ImageMagick-devel

4844329804
Amazon Web Services ガイドブック クラウドでWebサービスを作ろう!

4774146633
Ruby on Rails 3 アプリケーションプログラミング

関連記事

*1:合わせることでbundle exec rakeとしなくてもよくなる

2011-06-01

6月末で東京を離れます

突然のご報告的なエントリになりますが、6月末で地元の愛知に戻ることになりました。

理由

家庭の事情です。それ以上でも以下でもなく、普通に考えて実家での生活を優先すべき状況になったため、決断しました。

東京のこと

2010年1月中旬からなので、1年半くらい生活したことになります。基本ひきこもりでしたが、自由かつ快適な生活を満喫できた気がします。満員電車と無縁になるため、会社近くの部屋を借りたことがやはり大きな選択だったのかもしれません。IT系のイベントも大小問わず常に開催されており、圧倒的な地の利を感じました。

仕事のこと

主にはソーシャルアプリを、直近ではRailsシステム開発に携わりました。RailsのおかげでGit/VimCUIの世界にどっぷり浸かり、ひと周り成長できたような気がします。前職よりも大きな規模の会社でいろいろな人と仕事をすることができ、特に活気のある若い世代からは多くの刺激を受けました。また自分に近い部署で関わった中では、個人でブログを書いたり勉強会に参加したりする人も出てきて、そういった姿勢を少しでも伝えられたことは嬉しく思います。

これからのこと

明確には決まっていません。転職するかどうかは未定で、個人で得られる収入もわずかしかありません。家庭の中で自分にできることをしながら、ゆっくりと考えるつもりでいます。スマートフォン/海外(英語)/刺激し合えるエンジニア仲間、といった点を意識しつつ、何かしらの活動はしていきたいと思います。そしてチャンスが巡ってきたときには、自信を持って決断ができるように備えたいところです。

さいごに

東京に居られるのも1ヶ月を切りました。月末まで仕事をするのと引越し準備で慌ただしくはあるのですが、そんな中でも有意義に過ごせたらと思います。せっかくなので会って話してみたいなんて方がもしおられましたら、ご連絡いただけるとありがたいです。

ブログ/Twitterは変わらず更新していきますので、引き続きよろしくお願いします!