ActiveRecordで取得したテーブルのデータから選択リスト(プルダウン)を作成したいと思ったんです。 出張費精算のアプリを作っていて、"http://localhost/home/list/200707"というURLにアクセスすると、2007年7月のリストを出力する仕様になっています。これにプルダウンで月の選択をすると、リストが切り替わる様にしたいんです。 テーブルは月別の出張費精算テーブルで、こんな構成。
      create_table(:monthly_expenses, options) {|table|
        table.column :employee_id,        :integer
        table.column :appropriate_month,  :date
        table.column :period_from,        :date
        table.column :period_to,          :date
        table.column :total_amount,       :integer
        table.column :prepayment,         :integer
        table.column :report_date,        :date
        table.column :status,             :integer
        table.column :time_stamp,         :datetime
      }
選択リストはこの月別のリストを切り替える為に使いたいので、欲しいのは、" appropriate_month"だけだったりします。 ずいぶんと余分なモノが混じってしまっています。それだけならまだしも、URLとして使う都合上、"yyyy-MM-dd"形式ではなくて、"yyyyMM"を取得したい。選択リストのテキストには"yyyy年MM月"としてあげたい。 どうやっても変換をかける必要があるんですが、出来ればSQLを書かずにすませたい(単なるこだわりです)。 ActiveRecordに取得カラムを指定は出来ない様子。オブジェクト化するから、当然なんですけど。 取得結果をブロックで処理して、mapしてあげることにしました。
@monthly_list =
   MonthlyExpense.find(:all,
                :conditions => ["employee_id = ?", employee_id],
                :order => "appropriate_month"
                ).map { |m| [m.appropriate_month.strftime("%Y年%m月"),
                               m.appropriate_month.strftime("%Y%m")] }
あとは、rhtml側で、ActionHelperを使って、
<%= select(:month, :value, @monthly_list) %></pre>
としてあげれば、OK。 ではなくて、初期値を設定してあげないといけない。 selectの場合は、@month.valueに入っている値がリストにあれば、それを選択状態にしてくれるのですが・・・ monthオブジェクトはselectタグ内部で作成されていので、コントローラー側でセットしようにもオブジェクトが存在しない。 動的にオブジェクトを作成するほうほうが思い浮かばなかったので、クラス定義をしてまいました。
class Month 
  attr_accessor :value
end
@month = Month.new @month.value = @monthly_expense.appropriate_month.strftime("%Y%m")
すっごく強引な気がするけど、後で思いついたら直すことに。 最後にonChangeのイベントをとってリクエストを投げて挙げるように修正。 prototype.jsのEvent.observeを使う。
Event.observe($('month_value'), 
   "change", 
   function(){
    document.location.href = "/home/list/" + escape($F('month_value'));
   });
これで一応動作を確認。なんかもっと上手くできる気がするんですけどね。 とりあえず動けば官軍って言うんでこれで我慢します。