Reputation: 10551
In the rails console:
ActionDispatch::Http::UploadedFile.new tempfile: 'tempfilefoo', original_filename: 'filename_foo.jpg', content_type: 'content_type_foo', headers: 'headers_foo'
=> #<ActionDispatch::Http::UploadedFile:0x0000000548f3a0 @tempfile="tempfilefoo", @original_filename=nil, @content_type=nil, @headers=nil>
I can write a string to @tempfile
, and yet @original_filename
, @content_type
and @headers
remain as nil
Why is this and how can I write information to these attributes?
And how can I read these attributes from a file instance?
i.e.
File.new('path/to/file.png')
Upvotes: 3
Views: 3296
Reputation: 106077
It's not documented (and doesn't make much sense), but it looks like the options UploadedFile#initialize
takes are :tempfile
, :filename
, :type
and :head
:
def initialize(hash) # :nodoc:
@tempfile = hash[:tempfile]
raise(ArgumentError, ':tempfile is required') unless @tempfile
@original_filename = encode_filename(hash[:filename])
@content_type = hash[:type]
@headers = hash[:head]
end
Changing your invocation to this ought to work:
ActionDispatch::Http::UploadedFile.new tempfile: 'tempfilefoo',
filename: 'filename_foo.jpg', type: 'content_type_foo', head: 'headers_foo'
Or you can set them after initialization:
file = ActionDispatch::Http::UploadedFile.new tempfile: 'tempfilefoo', filename: 'filename_foo.jpg'
file.content_type = 'content_type_foo'
file.headers = 'headers_foo'
I'm not sure I understand your second question, "And how can I read these attributes from a file instance?"
You can extract the filename (or last component) from any path with File.basename
:
file = File.new('path/to/file.png')
File.basename(file.path) # => "file.png"
If you want to get the Content-Type that corresponds to a file extension, you can use Rails' Mime module:
type = Mime["png"] # => #<Mime::Type:... @synonyms=[], @symbol=:png, @string="text/png">
type.to_s # => "text/png"
You can put this together with File.extname
, which gives you the extension:
ext = File.extname("path/to/file.png") # => ".png"
ext = ext.sub(/^\./, '') # => "png" (drop the leading dot)
Mime[ext].to_s # => "text/png"
You can see a list of all of the MIME types Rails knows about by typing Mime::SET
in the Rails console, or looking at the source, which also shows you how to register other MIME types in case you're expecting other types of files.
Upvotes: 3
Reputation: 1624
the following should help you:
upload = ActionDispatch::Http::UploadedFile.new({
:tempfile => File.new("#{Rails.root}/relative_path/to/tempfilefoo") , #make sure this file exists
:filename => "filename_foo" # use this instead of original_filename
})
upload.headers = "headers_foo"
upload.content_type = "content_type_foo"
I didn't understand by "And how can I read these attributes from a file instance?", what you exactly want to do. Perhaps if you want to read the tempfile, you can use:
upload.read # -> content of tempfile
upload.rewind # -> rewinds the pointer back so that you can read it again.
Hope it helps :) And let me know if I have misunderstood.
Upvotes: 2