yo_waka's blog

418 I'm a teapot

Railsでセレクトボックスの出力

selectとかselect_tagとかcollection_selectとかいろいろあってオプションの指定も微妙に違ってたり分かりにくい。
ActiveRecordの配列と普通の配列を同じように扱えて、name属性を自由に定義したい。
いろいろ試してみたところ、select_tagとoptions_for_selectを使うのがよさげな感じがした。

<!-- ActiveRecordの配列を受け取る -->
<%= select_tag "user", options_for_select(@users.map {|u| [u.name, u.id]}), prompt: t('user') %>
<!-- 配列([name, id])を受け取る -->
<%= select_tag "status", options_for_select(@statuses), prompt: t('status') %>

selectとcollection_selectはname属性が"オブジェクト名[プロパティ名]"になる。
promptは未選択時の項目、空欄でよければinclude_blankをオプションに指定する。

Railsのroutes.rbでscopeとpathが便利だった

なんか日本語が不自由な感じ。。
Railsのroutes.rbで普通にresource(s)を使う場合はidを使ったURLルートが作られる。

resource 'foo' do
  resources 'bars'
end

# bundle exec routes
GET    /foo/:foo_id/bars(.:format)             bars#index
POST   /foo/:foo_id/bars(.:format)             bars#create
GET    /foo/:foo_id/bars/new(.:format)         bars#new
GET    /foo/:foo_id/bars/:id/edit(.:format)    bars#edit
GET    /foo/:foo_id/bars/:id(.:format)         bars#show
PATCH  /foo/:foo_id/bars/:id(.:format)         bars#update
PUT    /foo/:foo_id/bars/:id(.:format)         bars#update
DELETE /foo/:foo_id/bars/:id(.:format)         bars#destroy
POST   /foo(.:format)                         foo#create
GET    /foo/new(.:format)                     foo#new
GET    /foo/:id/edit(.:format)                foo#edit
GET    /foo/:id(.:format)                     foo#show
PATCH  /foo/:id(.:format)                     foo#update
PUT    /foo/:id(.:format)                     foo#update
DELETE /foo/:id(.:format)                     foo#destroy


でもidを見せたくなくて、ランダムなトークンでアクセスURLを作りたいとき。
「/foo/:id」ではなくて「/:token」、「/foo/:foo_id/bars」ではなくて「/:token/bars」でアクセスさせたい。
そういうときはscopeとpathを使うとスッキリ書ける。

scope ':token', :token => /\w{8}/ do
  resource 'foo', :path => '/' do
    resources 'bars'
  end
end

# bundle exec rake routes
GET    /:token/bars(.:format)                  bars#index {:token=>/\w{8}/}
POST   /:token/bars(.:format)                  bars#create {:token=>/\w{8}/}
GET    /:token/bars/new(.:format)              bars#new {:token=>/\w{8}/}
GET    /:token/bars/:id/edit(.:format)         bars#edit {:token=>/\w{8}/}
GET    /:token/bars/:id(.:format)              bars#show {:token=>/\w{8}/}
PATCH  /:token/bars/:id(.:format)              bars#update {:token=>/\w{8}/}
PUT    /:token/bars/:id(.:format)              bars#update {:token=>/\w{8}/}
DELETE /:token/bars/:id(.:format)              bars#destroy {:token=>/\w{8}/}
POST   /:token(.:format)                      foo#create {:token=>/\w{8}/}
GET    /:token/new(.:format)                  foo#new {:token=>/\w{8}/}
GET    /:token/edit(.:format)                 foo#edit {:token=>/\w{8}/}
GET    /:token(.:format)                      foo#show {:token=>/\w{8}/}
PATCH  /:token(.:format)                      foo#update {:token=>/\w{8}/}
PUT    /:token(.:format)                      foo#update {:token=>/\w{8}/}
DELETE /:token(.:format)                      foo#destroy {:token=>/\w{8}/}

あとは必要に応じて:onlyと:exceptでアクションを絞るだけ。

WebistranoをRails3.2.9に対応させた

アプリのデプロイやDBのマイグレーションCapistrano を使っているのですが、PM やディレクターでもテンプレートの修正くらいならコミットしてデプロイできるようなやり方をいろいろ探していて、Capistrano の WebUI であるWebistrano に行き着きました。

これめっちゃいいじゃん!と思って見てみると、なんと最後の更新が2年前でRailsも2.3ではないか・・


あきらめずにググってみたら、id:antipopさんがRails3.2.5対応しているのを発見した。神対応すぎる。
Webistranoをruby1.9.3-p194 + Rails 3.2.5で動くようにした
ペパボも Webistrano 使ってるのかー

ただ、記事にも書かれている通り、元のリポジトリからかなり変更が加わっている感じで外部ライブラリのアップデートで簡単に死ぬ感じはする。
デプロイツールのようなものは一旦取り入れると、簡単には変えられないし、安心してツールをバージョンアップしていくためにも依存ライブラリは極力減らしておきたいところ。


なので、めんどくさいけど元のリポジトリを fork して、id:antipop さんのリポジトリを参考にしながら、地道に現時点で最新のRails 3.2.9でテストがすべて通る状態にした。
mass-assignmentエラーとかライブラリ読み込めてないの解消とかくらいしかやってないですけど。

waka/webistrano

ユーザー認証は少なくともRails3の間はdeviceで大丈夫だろうという気がしているので採用。
あと prototype.js をやめて jquery を使うように変更。ほとんど JS 使ってる箇所ないけど。
文言も国際化した。これが一番めんどくさかったけど、文言が英語というだけで敬遠する人も多いし、SPOF をより排除しやすくするためにもどうしてもやっておきたかった。

簡易ではあるけどユーザーの権限も設定できて使いやすいですね。
これでレシピ登録して運用までいけるかどうか試してみたいと思います。

bundle install --path=vendor/bundler
bundle exec rake db:setup
bundle exec rake test
bundle exec script/rails s