Topic: file_field validation

Hello,

I want to write a little rails application that is able to upload files. To each file being uploaded, there should be a respective database entry (I do not want to store the files within the database due to potential high file sizes). As I was trying to validate the file_field (so that no file can be added to the database without actually uploading anything) I came to the following solution. However, this seems to be a bit uglym especially regarding to the controller code in the create function:

Controller - create

def create
    @data_file = DataFile.new(params[:data_file])
    @data_file.path=DataFile.get_path(params[:data_file])
    @data_file.size = 0

    respond_to do |format|
      if @data_file.save
        @data_file.size = DataFile.save_file(params[:data_file], @data_file.path)
        @data_file.save
        format.html { redirect_to @data_file, notice: 'Data file was successfully created.' }
        format.json { render json: @data_file, status: :created, location: @data_file }
      else
        format.html { render action: "new" }
        format.json { render json: @data_file.errors, status: :unprocessable_entity }
      end
    end
end

Model

class DataFile
  include Mongoid::Document
  field :name, type: String
  field :path, type: String
  field :size, type: Float

  attr_accessor :datafile
  validates :name, :path, :size, :presence  => true

  def self.save_file(upload, path)
    #write file
    File.open(path, "wb") { |f| f.write(upload[:datafile].read) }

    #return file size
    File.size(path).to_f/1024
  end

  def self.get_path(upload)
    if upload[:datafile]
      name = upload[:datafile].original_filename
      directory = "public/data"
      path = File.join(directory, name)
    end
  end

  def delete_file
    File.delete(self.path) if (self.path)
  end
end

View form

<%= form_for(@data_file) do |f| %>
  <% if @data_file.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@data_file.errors.count, "error") %> prohibited this data_file from being saved:</h2>

      <ul>
      <% @data_file.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>

  <div>
    <%= f.label("File") %><br />
    <%= f.file_field(:datafile) %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Is there perhaps any chance to check the file size in advance? Then it would be possible to avoid calling @data.save twice.

Thanks for your help!