180
178

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails でファイルをアップロードしてDBに登録する

Last updated at Posted at 2013-11-28

はじめに

gem を使わずに Rails の機能だけで、ファイルのアップロードを試してみます。

バージョン

  • ruby 2.0.0p247
  • Rails 4.0.0

今回は、アップロード可能な形式やファイルサイズの制限はしてません。

Model

class CreateContents < ActiveRecord::Migration
  def change
    create_table :contents do |t|
      t.string :upload_file_name
      t.binary :upload_file

      t.timestamps
    end
  end
end

モデル名は Content としています。
アップロードされたファイルを保存する upload_file をbinary、ファイル名を保存する upload_file_name を string で定義しています。

View

index.html.erb
<%= form_for(@content) do |f| %>
  <div class="field">
    <%= f.file_field :upload_file %>
  </div>
  <div class="actions">
    <%= f.submit "Upload" %>
  </div>
<% end %>

file_field を配置して、アップロードする form を作成する。

Controller

contents_controller.rb
  def create
    upload_file = content_params[:upload_file]
    content = {}
    if upload_file != nil
      content[:upload_file] = upload_file.read
      content[:upload_file_name] = upload_file.original_filename
    end
    content[:password] = content_params[:password]
    @content = Content.new(content)
    respond_to do |format|
      if @content.save
        format.html { redirect_to @content, notice: 'Upload success' }
        format.json { render action: 'show', status: :created, location: @content }
      else
        @contents = Content.all
        format.html { render action: 'index' }
        format.json { render json: @content.errors, status: :unprocessable_entity }
      end
    end
  end

create アクションに処理を書いていきます。
アップロードされたファイルの取得方法については、railsdoc の「アップロードされたファイルを取得」に詳しく載ってます。
content_params は strong_parameter です。

注意しなければいけないのは、アップロードされたファイルを直接DBに保存しようとするとエラーになります。
アップロードされたファイルは、 ActionDispatch::Http::UploadedFile クラスのオブジェクトであ
り、以下のようなインスタンスになっています。

#<ActionDispatch::Http::UploadedFile:0x007fe7ad501990
 @content_type="text/plain",
 @headers=
  "Content-Disposition: form-data; name=\"content[upload_file]\"; filename=\"test.txt\"\r\nContent-Type: text/plain\r\nContent-Length: 15\r\n",
 @original_filename="test.txt",
 @tempfile=
#<File:/var/folders/bg/3rk9r1y94_126k3231h0hvn40000gn/T/RackMultipart20131129-17450-zqlkd1>>

ファイル本体を取得するためには、@tempfile を read する必要があるんですが、UploadedFile クラスの read メソッドを利用することでことで出来ます。

ActionDispatch::Http::UploadedFile
def read(length=nil, buffer=nil)
  @tempfile.read(length, buffer)
end

そして、取得したバイナリデータを保存します。
ファイル名は @original_filename から取得しています。
以上で、ファイルのアップロードが出来るようになりました。

ActionDispatch::Http::UploadedFile クラスについては、以下の記事を参考にさせていただきました。ありがとうございました。
ActionDispatch::Http::UploadedFileを読む (デバックメモ)

180
178
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
180
178

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?