I have a very simple configuration for uploading files. I simply want to upload an image to a database (I know, I know...) with a description. That's it.
Here is what my model looks like (which I learned from here). Basically, it is exactly the way the example is setup, only with the attr_protected
line to work Rails 3.2:
Photo < ActiveRecord::Base
# note: there is also a :description attribute!!
attr_protected :file_name, :content_type, :binary_data
def image_file=(input_data)
self.file_name input_data.original_filename
self.content_type = input_data.content_type.chomp
self.binary_data = input_data.read
end
end
Here is what my very simple view looks like:
<h1>New Photo</h1>
<%= form_for(@photo) do |f| %>
<fieldset>
<legend>Upload a Photo</legend>
<div class="control-group">
<label class="control-label">Photo</label>
<div class="controls">
<%= f.file_field :image_file %>
</div>
</div>
<div class="control-group">
<%= f.label :description, class: "control-label" %>
<div class="controls">
<%= f.text_field :description, class: "text_field" %>
</div>
</div>
<div class="form-actions">
<%= f.submit "Upload", class: "btn btn-primary" %>
<%= link_to "Cancel", photos_path, class: "btn" %>
</div>
</fieldset>
<% end %>
And finally (merely for completeness), here is my Create action (simple scaffolding):
def create
@photo = Photo.new(params[:photo])
respond_to do |format|
if @photo.save
format.html { redirect_to @photo, notice: 'Photo was successfully created.' }
format.json { render json: @photo, status: :created, location: @photo }
else
format.html { render action: "new" }
format.json { render json: @photo.errors, status: :unprocessable_entity }
end
end
end
The idea is that the user will choose a file and type a small description which should post to a 'Create' method on the /photos
controller. Unfortunately when I click the submit button I get a very vague error that doesn't give me information about what the real problem is:
ArgumentError in PhotosController#create
wrong number of arguments (1 for 0)
Rails.root: /Users/me/dev/photo-app
Application Trace | Framework Trace | Full Trace
app/models/photo.rb:4:in `image_file='
app/controllers/photos_controller.rb:43:in `new'
app/controllers/photos_controller.rb:43:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"qSjMHgjCDo2ORmTvnujrljfPCj6oekLI9KAz4x5gA7Q=",
"photo"=>{"image_file"=>#<ActionDispatch::Http::UploadedFile:0x00000101726fd0 @original_filename="SomePic.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"photo[image_file]\"; filename=\"SomePic.jpg\"\r\nContent-Type: image/jpeg\r\n",
@tempfile=#<File:/var/folders/kc/8hsmx29j3xn2_j_9tsw8bz6w0000gn/T/RackMultipart20121001-52387-lre7zh>>,
"description"=>"my description"},
"commit"=>"Upload"}
I've looked all over Google and StackOverflow, but nothing seems to match my (very simple) example. Any help would be greatly appreciated!
Thanks in advance!
I took @kiddorails advice and implemented CarrierWave along with the Amazon Web Service. My project required image uploads and I was limited to Heroku. Therefore, I dove in and figured it out. In hind sight, it's the best solution, but at the time it seemed overkill for my (sample) project application. It was tricky for me (as a 'non-Ruby on Rails' developer).
At the end of the day, I would recommend anybody else who wishes to store images into a database to NOT do that, and do the same thing I did. Learn the right way to do it. :)
Here, image_file only contains the
ActionDispatch
object and not the content and description of the file as stated by :This looks absurd way of uploading a file. Either way, you will have to write content to your uploading location by reading
:tempfile