2011年6月9日木曜日

Rails:ファイルの添付の覚書(DBへではなく、ファイルを保存)その2

前回はプラグインを使わず、ファイルアップロードを行いました。

今回は、carrierwave を利用した場合の例です。

まず、carrierwave をインストールします。
尚、Railsのバージョンは2.3.11です。
現時点のcarrierwaveの最新バージョンは 0.5.4 ですが、こちらはRails3用のようです。
以下の処理でインストールされたのは 0.4.10 でした。

#{RAILS_ROOT}/Gemfile
source :rubygems

gem 'carrierwave', '~>0.4.0'

$ bundle
Fetching source index for http://rubygems.org/
Installing carrierwave (0.4.10) 
Using bundler (1.0.10) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.

少々待ちましたが、インストールされました。

$ ruby script/generate uploader attachment

app/uploaders/attachment_uploader.rb
が作成されます。

store_dirメソッドが自動生成されています。
こちらがファイルのアップロード先になります。
今回修正しました。

ちなみにSettingsは共通パラメータを設定するのに便利なsettingslogicをプラグインを導入し、外部のyamlファイルの設定を読み込めるようにしたものです。

 attr_accessor :sub_dir # 追加

  storage :file

  def store_dir
    #"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    Settings.upload_dir + "/#{sub_dir}"  # 追加
  end

Controller

私の場合、AttachmentUploaderクラスを利用するファイルで
carrierwaveをrequireする必要がありました。

require 'carrierwave'

  :

  uploader = AttachmentUploader.new
  uploader.sub_dir = @message.id.to_s
  uploader.store!(upload_file)

  :

Rails:ファイルの添付の覚書(DBへではなく、ファイルを保存)その1

Railsでファイルのアップロードの覚書

プラグイン(attacument_fu,paperclipedなど)を使わない方法

下記のコード例は、1画面で複数ファイルをアップロードする場合の例です。

VIEW

_from.html.erb



<% form_for @message , :url => { :action => action }, :html => {  :multipart => true, :id => 'message_form', :name => :message_form } do |f| %>
     :
      <% @message.attachments.each do |attach| %>
        <% if attach.id %>
          <% f.fields_for :attachments, attach do |attachment_form| %>
            <%= attachment_form.hidden_field :id %>
            <%= attachment_form.text_field :name %>
            Delete:<%= attachment_form.check_box :_destroy %><br />
          <% end %>
        <% else %>
          <% f.fields_for :attachments, attach do |attachment_form| %>
            <p>
            <%= attachment_form.hidden_field :id %>
            <%= attachment_form.label :path %>
            <%= attachment_form.file_field(:upload_data) %>
            </p>
          <% end %>
        <% end %>
      <% end %>
      :


Controller

    upload_files ||= []
    params[:message][:attachments_attributes].values.each do |attach|
      upload_file = attach[:upload_data]

      if upload_file
        upload_files << upload_file
      end

    end if params[:message][:attachments_attributes]

    respond_to do |format|
      if @message.save

        Dir.mkdir("#{Settings.upload_dir}#{@message.id}") if upload_files.count > 0
        upload_files.each do |upload_file|
          File.open("#{Settings.upload_dir}#{@message.id}/#{upload_file.original_filename}", "w+") { |f| f.write upload_file.read }
      end