UL/LIタグを使ってリストを表示するときに、 コレクションが空の場合はULタグを表示したくない場合というのが頻繁にあります。

   1  <% if @posts.present? %>
   2  <ul>
   3    <% @posts.each do |post| %>
   4    <li><%= h(@post.body) %></li>
   5    <% end %>
   6  </ul>
   7  <% end %>

そういう時は、だいたいこんな感じにコードを書きます。 しかし、条件が複雑になってきたり、複数のコレクションを考えなければ行けない場合に、きれいに記述出来なくなってきます。 そんな時は、以下のようなヘルパを使って、分岐条件を遅延評価するようにすると、処理が簡潔になります。

   1  module ApplicationHelper
   2    def delayed_if(&block)
   3      flag = Object.new
   4      def flag.set; @value = true end
   5      def flag.reset; @value = false end
   6      result = capture(&proc{block.call(flag)})
   7      concat(result) if flag.instance_variable_get(:@value)
   8    end

利用法

   1  <% delayed_if do |flag| %>
   2  <ul>
   3    <% @posts.each do |post| %>
   4    <li><%= h(@post.body) %></li>
   5    <% flag.set %>
   6    <% end %>
   7  </ul>
   8  <% end %>

flag.setがよばれた時だけ、delayed_ifのブロックが表示されます。 この例だと単純すぎてあまり恩恵が分かりにくいですが、 複数のコレクションを一つのULで表示する場合などでも簡潔に記述出来るようになります。

posted by Png genki on Sat 21 Mar 2009 at 22:45

リソースを新規に作成する場合に、既存のものを再利用して作成したい場合は良くあると思います。 そんな時は、newアクションで:idを受け取れるようにして、 以下のようにすると、簡単に実現出来ます。

   1    def new
   2      @post = Post.new
   3      @post.attributes = Post.find(params[:id]).attributes if params[:id]
   4      @posts = Post.for_user(current_user).all
   5    end

そしてposts/new.html.erbの中で

   1  <% if @posts.present? %>
   2  <form action=<%= new_post_path %> method="GET">
   3    <%= select_tag :id, options_for_select(@posts.map{|i| [i.title, i.id]}) %>
   4    <%= submit_tag '読み込む' %>
   5  </form>
   6  <% end %>

こんな感じに、テンプレートの読み込みフォームを作ります。 これで完了です。 Ajaxで posts/new/1 のようなURLにGETで遷移するようにした方が格好がいいかもしれません。

newアクションが:idで指定したリソースをテンプレートとして利用して新規にリソースを作成するというのは、標準的な挙動になっても良い気がします。

posted by Png genki on Sat 21 Mar 2009 at 13:47

前回の申請がリジェクトされたため、再申請いたしました。 細かい点の修正だけだったので、機能的には前回お知らせした内容のままです。

またもう数日お待たせする事になってしまい、申し訳ありません。

posted by Png genki on Fri 20 Mar 2009 at 00:44

久々にRailsモードが続いています。 APIを眺めていたら便利そうな機能を見つけたので紹介します。

layouts/application.html.erbの中などで、

   1  <%= javascript_include_tag :defaults %>

のように書く事があると思いますが、この:defaults というシンボルを指定することで、あらかじめ登録されている expansionが展開されてincludeされます。 この:defaultsのようなものを自分で登録したい場合、

   1  ActionView::Helpers::AssetTagHelper.register_javascript_expansion :foo => ["bar", "baz"]

のようにconfig/initializers/*あたりで登録しておけばOKです。 呼び出す時は

   1  <%= javascript_include_tag :foo %>

でOK。プラグインを作るとき等に、複数のjsフィアルをまとめてincludeできるようにしておくと便利ですね。

スタイルシートの場合は、register_stylesheet_expansionという同様のメソッドを使います。

posted by Png genki on Thu 19 Mar 2009 at 11:04

昨日の時点でTwitterでは話題になっていましたが、 正式にRails-2.3.2のリリースがアナウンスされたようです。

Rails 2.3: Templates, Engines, Rack, Metal, much more!

Rails 2.3 is finally done and out the door. This is one of the most substantial upgrades to Rails in a very long time.

今回のリリースの主な特徴は、

  • Templates: 自分好みのRailsアプリケーションのひな形を作る機能。 沢山Railsアプリを作ってる人には便利そう。
  • Engines: Railsアプリをコンポーネント化して再利用する仕組み。MerbのSliceのような印象。render_componentが無くなったので、代わりにこれを使うと良いらしい。
  • Rack: Rackに対応。
  • Metal: 色々と省略して高速なレスポンスを実現する仕組み。
  • Nested forms: 頭痛への処方箋。かなり嬉しい。

全体的な印象として、Merb-1.1との差が少なくなってきた感じですね。 Rails-3(あるいはMerb-2)への道筋が見えてきた気がします。

See Also

posted by Png genki on Tue 17 Mar 2009 at 09:30

便利そうなサービスを見つけたので紹介します。

RDocul.us

ss

いつでも最新のRDoc情報を配信してくれるサービスのようです。 ドキュメントはRDocがあればだいたい事足りるので、非常に助かります。

欲を言えばインクリメンタルサーチにも対応して欲しい :-)

posted by Png genki on Tue 17 Mar 2009 at 09:06

Merbと違って、Railsには標準的なユーザ認証機構が用意されていないので、 昔から様々な認証用プラグインが乱立していました。 login_generator, acts_as_authenticated, restful_authentication, restful_openid_authentication and so on...

今回は、@a_matsudaさんや @lchinさんの勧めもあり、 比較的新しいClearanceという認証プラグインを試してみる事にしました。

インストール方法

config/environment.rbに

   1    config.gem "thoughtbot-clearance", 
   2      :lib     => 'clearance', 
   3      :source  => 'http://gems.github.com',
   4      :version => '>= 0.5.3'

config/environments/test.rbに

   1  config.gem 'thoughtbot-shoulda',
   2    :lib     => 'shoulda',
   3    :source  => "http://gems.github.com", 
   4    :version => '>= 2.10.0'
   5  config.gem 'thoughtbot-factory_girl',
   6    :lib     => 'factory_girl',
   7    :source  => "http://gems.github.com", 
   8    :version => '>= 1.2.0'

と記述し、

   1  % sudo rake gems:install
   2  % sudo rake gems:install RAILS_ENV=test

あとは、

   1  % ./script/generate clearance

これでモデル、コントローラ、View、migrationファイルの作成が行われ、 マイグレーションの実行まで完了します。

続いて、config/environments/*.rb に、HOST="hostname"のようにホスト名を設定します。test, developmentでは"localhost"、 productionでは実際に使われるホスト名を指定すれば良いようです。 さらに、config/environment.rbの中で、

   1  DO_NOT_REPLY = 'do_not_reply@s21g.com'

のように、アクティベーションメールの送信もとメールアドレスを設定します。

最後に、config/routes.rbの中で、何でも良いのでrootのNamedRouteを定義します。

   1  map.root :controller => 'top'

以上で完了です。

追記

現時点でのバージョン(thoughtbot-clearance (0.5.3), thoughtbot-factory_girl (1.2.0), thoughtbot-shoulda (2.10.1))では、 clearanceに含まれているshoulda_macrosを手動でtest ディレクトリの下にコピーする必要があるようです。

See Also

posted by Png genki on Mon 16 Mar 2009 at 16:00
posted by Png genki on Mon 16 Mar 2009 at 00:05

Skitchはスクリーンショットをとったり、図を描いたり、 画像形式を変換したりと、非常に便利な画像処理ツールで、 愛用しています。

コマンドラインからSkitchを起動出来たら便利だな、 と思って試したら、すんなり出来たので紹介します。

   1  % /Applications/Skitch.app/Contents/MacOS/Skitch foo.png

こんな感じでOK。convertコマンドの代わりになるかも。

posted by Png genki on Sun 15 Mar 2009 at 09:54

Gaiji for iPhone is the feature of PokéDia-1.3 that we've submitted last week. It provides a custom keyboard of external characters. Seeing is believing, please look at this video.

In this video, a set of external characters (labeled as "Arrows") were downloaded from the site (http://gaiji.s21g.com).

See Also

posted by Png takiuchi on Sun 15 Mar 2009 at 06:58