NetBeans6.5日本語版 正式リリース

ここんとこ本当に本業が忙しすぎて自宅のPCの前に座ることすら
できない状況に。しかも朝が寒くなってきたので、ふとんから
出ることができず、朝に強い自分もなかなか起きれない事に。
で、久し振りに立ち上げてみるといつの間にやらNetBeans6.5日本語版
の正式リリースのアナウンスが…。
早速インストールしました。元々使いこなしてなかったので、
どこがどう変わったかはあまりわからなかったりする。
でも「タスク」ウィンドウが開いてなんだか自動的にエラーを
検出して一覧が表示されてるのはわかった。
便利そう。…でも使える時間が無いんだよな、これが…。

ちょっと変更

久しぶりに日記。本業が忙しすぎて、何もできず。
少しだけファイルのアップダウンの処理を変更。
サーバに保存するファイル名がURLエンコードになるのはいやだったので、
レコードのIDで保存するように変更。

  def create
    upload = params[:doc]
    doc = Document.create( :filename=>upload['file'].original_filename )
    path = "/files/" +doc.id.to_s;
    File.open( path, "wb") { |f| f.write( upload['file'].read ) }
  end

  def download
    doc = Document.find(params[:id])
    path = "/files/" + doc.id.to_s;
    send_file(path, :filename => filename_for_content_disposition(doc.filename))
  end

FireFoxを入れてうまくいくか試した。OKだね。IEだとやっぱりURLエンコードのファイル名で
オープンされてしまう。
いろいろサイトを調べるとiconvを使っている人が多い。
今度これを試してみよう。

漢字ファイルのダウンロード

漢字ファイルのダウンロードでエラーになる部分は、redmineを参考にしてみた。
application.rbのメソッド

  def filename_for_content_disposition(name)
    request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
  end

HTML素人なので、全部調べた。
"request"はブラウザが送ってきたオブジェクト。
"env['HTTP_USER_AGENT']"は、ブラウザの情報が入ってる。
"=~ %r{MSIE}"は、正規表現のマッチング。
ここまでで、"ブラウザがIEか?"ってことらしい。
IE7は次の情報を送ってくる。

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)

で、"ERB::Util.url_encode(name)"の部分は、URLエンコードってやつで、
%付きの文字列にしてくれる。これで漢字の部分は"%E6%BC%A2%E5…"に変換される。
これでファイルへの保存とsend_fileに引き渡すときに変換してやる。
こんな感じ。

  def create
    upload = params[:doc]
    path = "/files/" + filename_for_content_disposition(upload['file'].original_filename)
    File.open( path, "wb") { |f| f.write( upload['file'].read ) }

    Document.create( :filename=>upload['file'].original_filename )
  end

  def download
    document = Document.find(params[:id])
    path = "/files/" + filename_for_content_disposition(document.filename)
    send_file(path)
  end

いくつか問題あり。
・ファイルの保存ダイアログの確認表示でファイル名に空白があると%20となる。
・実際に保存されたファイル名は%付きなので何が何だかわからない。
一応、うまくいった。
これで思ったのは、IE以外も試さないといけないということ。
FireFoxとかで試してみるか。

また漢字に関するエラー

Railsでファイルのダウンロードができた〜…と思っていたが、
なんだかうまくいかない状況がある。しかも2つ。
一つ目は、ファイルのダウンロードで、日本語ファイル名を使用すると

Cannot read file /files/漢字ファイル.txt

と表示される。アップロードはできたのに?ダウンロードはできないの?
もう一つはWEBrickのエラー。
大きなファイルをダウンロードしようとするとWEBrickのコンソールにエラーが出る。
IOError。これは何となくわかるけど、続く文字が文字化けしてる。
これもよくわからなかったので、試しにglassfishを使ってみることにした。
(最近NetBeans6.5をBetaからDevelopmentバージョンに変えたついでに入れた)。
プロジェクトのプロパティでWEBrickからglassfishに変更。
サーバは動いたんだけど…何にもWEBページ出ません。
さてどれから解決していこう…タイムリミット。明日調べます。

ファイルのダウンロード

Railsでファイルのダウンロードを作ってみよう。
前回の続きで、モデルdocumentを作成する。項目はファイル名(filename:string)。
NetBeansだと、プロジェクトの「生成...」からmodelを選択して、引数に

document filename:string

を入力する。
データベースのマイグレーションも「現在のバージョンへ」を選択し作成。
ビューはこんな感じで(index.html.rb)。

<table>
  <tr>
    <th>ファイル名</th>
  </tr>
<% @documents.each do |document| %>
  <tr>
    <td><%= link_to( h(document.filename),
    {:controller=>"document",:action=>"download",:id=>document.id } )%>
    </td>
  </tr>
<% end %>
</table>

ローカルホストの/document/indexを参照するとファイル名の一覧が表示される。
ダウンロードするメソッド「download」をコントローラに追加する。

  def download
    document = Document.find(params[:id])
    path = "/files/" + document.filename
    send_file(path)
  end

テーブルdocumentのfilenameにファイル名を入れ、filesフォルダ下に実際のファイルを保存する。
一覧にはテーブルのfilenameを表示し、ダウンロードの時にfilesフォルダ下のファイルを送る仕組みだ。
これでファイルのダウンロードはできたぞ。

ようやく簡単なファイルのアップロード

まずはRailsのビューとコントローラだけでファイルのアップロードを作成
ビューの方はこんな感じ(new.html.erb)

<% form_tag({:controller => 'document', :action => 'create'}, :multipart => true) do %>
<%= file_field :doc, 'file' %><br/>
<%= submit_tag '登録' %>
<% end %>

でコントローラの方は、こんな感じ(document.controller.rb)

  def new
  end

  def create
    upload = params[:doc]
    path = "/files/" + upload['file'].original_filename
    File.open( path, "wb") { |f| f.write( upload['file'].read ) }
  end

最初にコントローラdocumentとnewメソッド、createメソッドを作って
上記のコードを入れる。ローカルホストの/document/newにアクセスすると、
ファイルアップロードの画面が出るので、ファイル名を入力し、登録ボタンを
押すとプロジェクトのfilesフォルダ下にファイルが作成される。
(プロジェクトフォルダの下にfllesフォルダを事前に作成しておく)
たったこれだけで完成なのに1週間悩んだ。

scaffoldから作ると大変

form_forとかのリファレンスを読むと、いろんな書き方があって、何がなんだか。
しかもscaffoldから生成されたコードはシンプルなんだけど、それが余計にわからなくなってきた。
やはり地道にコツコツと勉強すべし。
scaffoldを使用せずに、モデルを作り、コントローラとビューを作り、…という具合にやっていこう。
ついでに途中で調べたrespond_toの覚書。要するにrespond_toは、mimeタイプ(htmlとかxmlとか)を
見て、それに合わせた描画を指定できる。mimeタイプ毎に処理を分けずに済むということらしい。
scaffoldの出力は、respond_toで処理されている。メソッドの注釈を見ればアクセス方法は
なんとなくわかった。