感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

ファイルをアップロードしてみる

<スポンサーリンク>

Railsで写真をアップロードしてみましょう。
ファイルを選択して、「アップロード」というボタンを押せば、ファイルをサーバ上にアップロードできます。
ビューは以下のように書きます。

<%= form_tag 'samples/index', :multipart =>true do %>
  <label>保存したいファイル:<br/>
  <%= file_field_tag :uppic, :size => 100 %></label>
  <%= submit_tag 'アップロード' %>
<% end %>

注意すべきは、
file_field_tagのところで指定する「:uppic」のタグ。

これは、コントローラ側で、params[:uppic]というように、パラメータ名(=:uppic)を正しく指定しないと、以下のようなエラーが出ます。

undefined method `original_filename' for nil:NilClass

これは何かというと、たとえば、

file = params[:uphogefuga]

みたいに間違ったパラメータ名を指定してしまったとき、パラメータの内容が取得できない!
だから、fileのインスタンスがないよ。nilだよって意味です。

俺は参考にした本(ポケットリファレンス)を真似していたんですが、ここでハマりました(笑)
たぶん誤植ですよね?

気を撮り直して、コントローラ側はこんな風に書きます。
ビューのところでは、「form_tag 'samples/index'」とやっているので、
コントローラ側では「def index」の部分が呼ばれます。

あと、routes.rbに

  post "samples/index"

を追記しておくことも忘れないで下さい。
rails generate controllerではgetしか作られないはずなので。

class SamplesController < ApplicationController
  def index
    file = params[:uppic]
    
    name = file.original_filename
    if !['.jpg', '.gif', '.png'].include?(File.extname(name).downcase)
      msg = 'アップロードできるのは画像だけ'
    elsif file.size > 10.megabyte
      msg = 'アップロードは10メガバイトまで'
    else
      name = name.kconv(Kconv::SJIS, Kconv::UTF8)
      File.open("tmp/pics/#{name}", 'wb') { |f| f.write(file.read) }
      msg = "#{name.toutf8}のアップロードに成功しました"
    end

    render :text => msg
  end

end

これでアップロードがうまくいくと、
myapps(アプリケーションのルート)/tmp/pics以下には、

「IMG_0030.jpg」というファイルが格納されます。
ブラウザには、

IMG_0030.jpgのアップロードに成功しました

と表示されます。

【参考文献】
Ruby on Rails 3 ポケットリファレンス

http://railsdoc.com/references/params