Module: Ramaze::Helper::Upload

Includes:
Traited
Defined in:
lib/ramaze/helper/upload.rb

Overview

Helper module for handling file uploads. File uploads are mostly handled by Rack, but this helper adds some convenience methods for handling and saving the uploaded files.

Examples:

class MyController < Ramaze::Controller
  # Use upload helper
  helper :upload

  # This action will handle *all* uploaded files
  def handleupload1
    # Iterate over uploaded files and save them in the
    # '/uploads/myapp' directory
    get_uploaded_files.each_pair do |k, v|
      v.save(
        File.join('/uploads/myapp', v.filename),
        :allow_overwrite => true
      )

      if v.saved?
        Ramaze::Log.info(
          "Saved uploaded file named #{k} to #{v.path}."
        )
      else
        Ramaze::Log.warn("Failed to save file named #{k}.")
      end
    end
  end

  # This action will handle uploaded files beginning with 'up'
  def handleupload2
    # Iterate over uploaded files and save them in the
    # '/uploads/myapp' directory
    get_uploaded_files(/^up.*/).each_pair do |k, v|
      v.save(
        File.join('/uploads/myapp', v.filename),
        :allow_overwrite => true
      )

      if v.saved?
        Ramaze::Log.info(
          "Saved uploaded file named #{k} to #{v.path}."
        )
      else
        Ramaze::Log.warn("Failed to save file named #{k}.")
      end
    end
  end
end

Author:

Since:

Defined Under Namespace

Modules: ClassMethods Classes: UploadedFile

Class Method Summary (collapse)

Instance Method Summary (collapse)

Class Method Details

+ (Object) included(mod)

Adds some class method to the controller whenever the helper is included.

Since:

  • 04-08-2011



173
174
175
# File 'lib/ramaze/helper/upload.rb', line 173

def self.included(mod)
  mod.extend(ClassMethods)
end

Instance Method Details

- (Array) get_uploaded_files(pattern = nil)

This method will iterate through all request parameters and convert those parameters which represents uploaded files to Ramaze::Helper::Upload::UploadedFile objects. The matched parameters will then be removed from the request parameter hash.

Use this method if you want to decide whether to handle file uploads in your action at runtime. For automatic handling, use Ramaze::Helper::Upload::ClassMethods#handle_all_uploads or Ramaze::Helper::Upload::ClassMethods#handle_uploads_for instead.

Parameters:

  • pattern (Regexp) (defaults to: nil)

    If set, only those request parameters which has a name matching the Regexp will be checked for file uploads.

Returns:

  • (Array)

    The uploaded files.

See Also:

Author:

  • Lars Olsson

Since:

  • 04-08-2011



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/ramaze/helper/upload.rb', line 79

def get_uploaded_files(pattern = nil)
  uploaded_files = {}

  # Iterate over all request parameters
  request.params.each_pair do |k, v|
    # If we use a pattern, check that it matches
    if pattern.nil? or pattern =~ k
      # Rack supports request parameters with either a single value or
      # an array of values. To support both, we need to check if the
      # current parameter is an array or not.
      if v.is_a?(Array)
        # Got an array. Iterate through it and check for uploaded files
        file_indices = []

        v.each_with_index do |elem, idx|
          file_indices.push(idx) if is_uploaded_file?(elem)
        end

        # Convert found uploaded files to
        # Ramaze::Helper::Upload::UploadedFile objects
        file_elems = []

        file_indices.each do |fi|
          file_elems << Ramaze::Helper::Upload::UploadedFile.new(
            v[fi][:filename],
            v[fi][:type],
            v[fi][:tempfile],
            ancestral_trait[:upload_options] ||
            Ramaze::Helper::Upload::ClassMethods.trait[
              :default_upload_options
            ]
          )
        end

        # Remove uploaded files from current request param
        file_indices.reverse_each do |fi|
          v.delete_at(fi)
        end

        # If the request parameter contained at least one file upload,
        # add upload(s) to the list of uploaded files
        uploaded_files[k] = file_elems unless file_elems.empty?

        # Delete parameter from request parameter array if it doesn't
        # contain any other elements.
        request.params.delete(k) if v.empty?
      else
        # Got a single value. Check if it is an uploaded file
        if is_uploaded_file?(v)
          # The current parameter represents an uploaded file.
          # Convert the parameter to a
          # Ramaze::Helper::Upload::UploadedFile object
          uploaded_files[k] = Ramaze::Helper::Upload::UploadedFile.new(
            v[:filename],
            v[:type],
            v[:tempfile],
            ancestral_trait[:upload_options] ||
            Ramaze::Helper::Upload::ClassMethods.trait[
              :default_upload_options
            ]
          )

          # Delete parameter from request parameter array
          request.params.delete(k)
        end
      end
    end
  end

  # If at least one file upload matched, override the uploaded_files
  # method with a singleton method that returns the list of uploaded
  # files. Doing things this way allows us to store the list of uploaded
  # files without using an instance variable.
  unless uploaded_files.empty?
    @_ramaze_uploaded_files = uploaded_files

    # Save uploaded files if autosave is set to true
    if ancestral_trait[:upload_options] and
       ancestral_trait[:upload_options][:autosave]
      uploaded_files().each_value do |uf|
        uf.save
      end
    end
  end

  # The () is required, otherwise the name would collide with the variable
  # "uploaded_files".
  return uploaded_files()
end

- (Boolean) is_uploaded_file?(param) (private)

Returns whether +param+ is considered an uploaded file A parameter is considered to be an uploaded file if it is a hash and contains all parameters that Rack assigns to an uploaded file

Parameters:

  • param (Hash)

    A request parameter

Returns:

  • (Boolean)

Since:

  • 04-08-2011



205
206
207
208
209
210
211
212
213
214
215
# File 'lib/ramaze/helper/upload.rb', line 205

def is_uploaded_file?(param)
  if param.respond_to?(:has_key?)
    [:filename, :type, :name, :tempfile, :head].each do |k|
      return false if !param.has_key?(k)
    end

    return true
  else
    return false
  end
end

- (Hash) uploaded_files

Returns list of currently handled file uploads.

Both single and array parameters are supported. If you give your file upload fields the same name (for instance upload[]) Rack will merge them into a single parameter. The upload helper will keep this structure so that whenever the request parameter contains an array, the uploaded_files method will also return an array of Ramaze::Helper::Upload::UploadedFile objects for the same key.

Returns:

  • (Hash)

    Currently uploaded files. The keys in the hash corresponds to the names of the request parameters that contained file uploads and the values consist of Ramaze::Helper::Upload::UploadedFile objects.

Since:

  • 04-08-2011



192
193
194
# File 'lib/ramaze/helper/upload.rb', line 192

def uploaded_files
  return @_ramaze_uploaded_files || {}
end