Rails3でクエリパラメータでルーティング(Advanced Constraints)
少し前にsendagaya.rbで発表したRails3のAdvanced Constraintsをここでも紹介。
routes.rbの中でURLを定義する時にsubdomainとかを条件に含めるときに使うのがconstraintsというオプションなんですが、これを使ってURLの「?」以降を条件にしたりもできます。
方法はrequestオブジェクトを受け付けるmatches?というメソッドを実装したクラスを定義してインスタンスをconstraintsに渡してあげるだけです。
ここではpostというリソースの集合であるindex、つまり /posts というURLにGETで ?q=hoge 等のパラメータが付いている時に posts_controller#search というアクションに紐付けるということを行なっています。
ただしこのままだと q に対するvalueが空の状態 /posts?q でもsearchアクションに処理が渡るので、コントローラ側で何かしらの対応が必要です。
基本的にはrequestオブジェクトを使って判別できるならどんな条件でもいいので、Accept-languageで振り分けるとかIPアドレスでブラックリストを作るとかもできてしまいます。
今回はindexアクションの中でifで分岐させておくことでも十分対応可能ですが、render以外はほとんど共通処理がないよとかになると、アクションそのものを分けてしまったほうが綺麗なコードになりそうですよね。
オープンソースになったTextMate2をbuildしてみた
すっかりVimに慣れてしまった今日この頃ですが、お世話になったTextMateの2がオープンソースになったのでbuildしてみました。ちなみに環境は OS X lion 10.7.4です。
-
Githubへ行ってみる
https://github.com/textmate/textmate.git
READMEにbuild方法は書かれていますね。
-
必要なライブラリをインストール
とりあえず brew install ragel boost multimarkdown hg ninja とやってみたのですが ninja なんてないよって怒られちゃいました
というわけで先に brew update してから再度実行したらちゃんと入りました
-
リポジトリをclone
git clone https://github.com/textmate/textmate.git でホームディレクトリにcloneしました
textmate というフォルダができているはずなのでそこに移動 cd textmate
-
build実行
の前に、READMEをみると git submodule update --init とやってねと書いてあるので実行
そして ./configure && ninja 実行!したら clang が古いと言われてしまいました
brew install --HEAD llvm --with-clang で入るはずなんですが、Error: can't convert nil into String とか言われる
brew update も brew doctor も問題ないんだよなぁ
Githubのbug-fixing-checklistを見るとXCodeのupdateして見た方が良さそうだなと思ったので Apple からCommando line tools for XCodeの割と最近のやつをDLした
でやり直しても駄目だなぁ。とよく見てみたらXCode 4.4+と書いてある、手元のXCodeは4.3でした。App Storeから入れ直そう。
-
XCodeをupdateしたので
気を取り直して ./configure && ninja を再度実行してみた。そしたら今度は pgrep が無いよと言われた
brew install pgrep を実行。(そろそろめんどくさくなってきた)
./configure && ninja よし。こんどこそうまく行ってそう。(なにやらwarningとかdepricatedが出てきてますが)
-
build成功した
やっと成功した。
へー2からはPreferencesでbundleとかthemeを追加できるようになってるんですね。逆に言うと最初は何も入ってないからハイライトも何も無いのだけど。
めでたし
bashでgitの現在のbranch名を表示させる
git-completionというシェルスクリプトを使えばできるということを知ったのでやってみた。
-
gitのバージョンを調べる
$ git --version $ 1.7.7.5
-
github(http://github.com/gitster/git)に行きcodeのtreeを同じバージョンに切り替える(ブランチの切り替え部分と同じところです)
-
git-completion.bashまでtreeをたどりraw表示に切り替えて保存
自分はhttps://raw.github.com/gitster/git/v1.7.7.5/contrib/completion/git-completion.bashでした -
DLしたファイルに使い方は大体書いてあるのでその通りにやれば動くと思います
$ cd ~ $ mv git-completion.bash .git-completion.sh $ vim .bashrc (or .bash_profile) $ PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' を追記 $ source .bashrc
-
こんなかんじで表示されました
[kozo@kozo-mp current_dir (master)]$
OS X Mountain Lionにアップデートした
早速OS X Mountain Lionにアップデートしたのでいくつか作業を記録します。
- App StoreからMountain Lionをダウンロード
- インストーラをコピーしておく
- インストールで暫し待つ(40分くらい)
- App StoreからXCodeをインストール
- iTerm2を立ちあげておもむろに
git --versionと打ってみた→消されてる! - ググったらこんなの発見
-
XCodeを立ち上げてPreferences経由でcommand line toolsをインストール
- git --versionでインストールを確認
- Homebrewのアップデート
- imagemagickが再インストール必要みたいなので一旦brew remove imagemagick
-
brew install imagemagick --use-gccとやるとXQuartzがないよと言われる
- http://xquartz.macosforge.org/trac/wiki/X112.7.2 からdmgをDLしてインストーラを実行
-
再度 brew install imagemagick --use-gcc を実行
- gccがみつからないらしく失敗
- めんどくさくなったので --use-gcc オプションを消してインストール
- で、何?感やばい
IE9でiframe内で遷移した場合window.parentのメソッドを呼べない
状況としては、ビデオ一覧ページから各ビデオをiframeを使ったレイヤーで立ち上げるページにて
ビデオはMediaElement.jsというのを使っていて、HTML5対応の判別して、ダメならFlashとかSilverlightとかに切り替えてくれるようになってます。(何も再生手段がなければmp4をDLさせます)
閉じるボタンを押してもビデオが再生されたまま
↓
iframeが非表示になっただけでページ内に生きているから
↓
レイヤーを表示させてるjsを調べる
なんだこれ誰かの自作じゃねえか!closeイベントとか取れねえよ!
↓
親ウィンドウから子iframeにアクセスするか、
子iframeから親ウィンドウに渡すか
後者を選択して window.parent.videos.push(video)
親のレイヤーを非表示にするときの処理に
if (window.videos) {
for (var i in window.videos) {
if (!window.videos[i].paused) {
window.videos[i].pause();
}
}
}
というのを挟むようにした。
IE、他ブラウザほぼ動く。
↓
IE9だけ動かない!
iframe内で次の動画へ遷移できるようにしてあったんだけど
ビデオのhtmlは一本につき1ファイルなのでこれは単純にリンクを押してるだけ
親から直接ではなくiframe内で遷移後にエラーする。
(でもIEのステータスバーにはエラー表示が出ないんだけどね)
↓
IE9のF12開発者ツールでブレークポイントつけてみる
「解放されたスクリプトからコードを実行できません」
ハァ(゚д゚)?
↓
ググってみた。あぁそういえばIEではJavaScriptじゃなくてJScriptだったな……
つまり信頼性の低いスクリプトから親ウィンドウにあるオブジェクトのメソッドを実行できないってことですかね!!
というわけでpushじゃなくて代入にした。
window.parent.videos[window.parent.videos.length] = video;
↓
動いた!
プロパティの参照と代入は問題ないみたいです。
CentOS 6 でRails + thin + nginxを動かした
thinってオワコンじゃないですよね?herokuで採用されているし別にいいですよね。
本当はunicorn使いたかったんですが難しい…… ><;
ぐぐると記事沢山出てきますが uninitialized constant errorで起動しない問題が解決できなくてやめちゃいました。いつかリベンジします。
CentOS 6
マシンはvagrant使ってcentos6を用意しました。
参考:http://www.ryuzee.com/contents/blog/4292
vagrantって便利ですね。元々Virtual Boxでwindows動かしてたのですんなりです。ホントに。するっと。
IPアドレスと
config.vm.network :hostonly, "192.168.33.10"
メモリとnameを設定しておきました
config.vm.customize do |vm| vm.memory_size = 1024 vm.name = 'vagrant_centos6' end
Ruby
rbenv + ruby-buildで1.9.3-p194をインストール
Thin
Gemfileのgroup :productionにgem 'thin'を追加して普通にbundle install
config/thin.ymlは
pid: tmp/pids/thin.pid log: log/thin.log servers: 1 port: 3000 daemonize: true environment: production user: vagrant group: staff
以下で起動、停止、再起動
$ be thin start|stop|restart -C config/thin.yml
Nginx
yumでnginxをインストール(参考:http://blog.livedoor.jp/sasata299/archives/51810645.html)
/etc/nginx/nginx.confは
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
# include /etc/nginx/conf.d/*.conf;
upstream backend {
server localhost:3000;
}
upstream backend2 {
server localhost:3001;
}
server {
listen 80;
server_name centos6.vag;
location / {
proxy_pass http://backend;
}
}
server {
listen 80;
server_name 2.centos6.vag;
location / {
proxy_pass http://backend2;
}
}
}
試す
あとはmacのhostsに
192.168.33.10 centos6.vag 192.168.33.10 2.centos6.vag
を設定してブラウザでアクセス!
サクセス!
でもnginx.confの書き方冗長だなぁもっといいのあるんだろうか。
※追記
上記の状態で試しに request.url を覗いてみたら http://backend2/ とかでちゃったよ!困るよ!
というわけでnginx.confを一部修正してみたら問題なく動いた
...省略...
upstream 2.centos6.vag {
server localhost:3001;
}
server {
listen 80;
server_name 2.centos6.vag;
location / {
proxy_pass http://2.centos6.vag;
}
}
...省略...
request.url でhttp://2.centos6.vagが返ってきた!
※追記2
画像など静的ファイルが返らないことがわかったので以下のようにconfig修正
server {
listen 80;
server_name 2.centos6.vag;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_max_temp_file_size 0;
location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO) {
root /home/vagrant/sample2/public;
ssi on;
break;
}
location / {
proxy_pass http://2.centos6.vag;
}
}
※追記3
thinの再起動などダウンタイムにnginxのデフォルトエラーページが返されるのでconfig追加
error_page 500 502 503 504 /500.html;↲
location = /500.html {↲
root /home/vagrant/sample2/public;↲
}
※追記4
マシンを再起動したときにthinも自動起動するようにした!
/etc/init.d/sampleを作成
#!/bin/sh # chkconfig: 2345 86 25 # description: Sample # PATH=/home/vagrant/.rbenv/shims:/home/vagrant/.rbenv/bin:$PATH eval "$(rbenv init -)" APP_DIR=/home/vagrant/sample THIN_CONFIG=$APP_DIR/config/thin.yml case $1 in start) cd $APP_DIR bundle exec thin start -C $THIN_CONFIG ;; stop) cd $APP_DIR bundle exec thin stop -C $THIN_CONFIG ;; restart) cd $APP_DIR bundle exec thin restart -C $THIN_CONFIG ;; esac exit 0
登録する
$ sudo /etc/init.d/sample start $ sudo chkconfig sample on



