I'm trying to upload an image file to my rails server, but I keep hitting a wall.
This is my form themed_controller/new
,
= form_for(@campaign, validate: true, :html => {:multipart => true}) do
.form-group
%label.col-sm-3.control-label
Campaign Name
.col-sm-6
%input#title.form-input{ name: "@campaign[campaign_title]", placeholder: "Campaign Title", required: "", type: "text", value: ""}/
.form-group
%label.col-sm-3.control-label
Campaign Description
.col-sm-6
%textarea.form-input{ name: "@campaign[campaign_description]", placeholder: "Campaign Description", required: "", value: ""}
.form-group
%label.col-sm-3.control-label
Pick stories
.col-sm-6
%select#themed_campaign_live_story_ids{name: "@campaign[live_story_ids][]", :multiple => true, :required=> true, value: []}
-# = f.select 'live_story_ids[]', [], :multiple => true
#date-range
.form-group#valid-from
%label.col-sm-3.control-label
Campaign runs from
.col-sm-6
%input.form-input#themed_campaign_valid_from{ name: "@campaign[valid_from]",:class => 'jquery-ui-date valid-from', :data => {:provide =>"datepicker", :behaviour => "datepicker"}, required: "", type: "text", value: ""}/
.form-group#valid-till
%label.col-sm-3.control-label
Campaign runs till
.col-sm-6
%input.form-input#themed_campaign_valid_till{ name: "@campaign[valid_till]",:class => 'jquery-ui-date valid-till', :data => {:provide =>"datepicker", :behaviour => "datepicker"}, required: "", type: "text", value: ""}/
.form-group#valid-till
%label.col-sm-3.control-label
Upload cover (1280x350)
.col-sm-6
-#upload-image.btn.btn-medium.btn-green{ :data => {:url => "/campaign/upload"} }
#upload-image
%input#image_media{name: "@campaign[cover]", type: "file"}/
.form-group
.col-sm-offset-3.col-sm-6
%button.form-button.btn-large.btn-green.btn#campaign-submit{type: "submit"}
Set up Campaign
And this is my create method
def create
campaign = params[:@campaign]
campaign['added_by_email'] = current_user.email
@campaign = ThemedCampaign.create(campaign)
if @campaign.save
img_attr = params[:@campaign]['cover']
image = Campaign.new img_attr
@campaign.cover = image
Resque.enqueue(ImageQueue,image.id)
#render :json => image.to_jq_upload.to_json
end
redirect_to '/admin/themecampaign'
end
I have created a seperate uploader for this,
# encoding: utf-8
class CampaignUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
before :cache, :save_original_filename
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg png)
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/campaigns/#{model.id}/"
end
end
And this is my campaign modal, which hold the image
class Campaign
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Paranoia
include Rails.application.routes.url_helpers
mount_uploader :cover, CampaignUploader
end
Now when I upload the form I keep getting an undefined method
empty?' for #
> NoMethodError - undefined method `empty?' for
> #<ActionDispatch::Http::UploadedFile:0x00000109968c50>: () Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/attributes/processing.rb:21:in
> `process_attributes' ()
> Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/document.rb:111:in `block in initialize' ()
> Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/threaded/lifecycle.rb:84:in
> `_building' ()
> Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/bundler/gems/mongoid-bc72426681d5/lib/mongoid/document.rb:105:in `initialize' actionpack (4.0.2)
> lib/action_dispatch/routing/url_for.rb:104:in `initialize'
> app/controllers/themed_campaign_controller.rb:57:in `new'
> app/controllers/themed_campaign_controller.rb:57:in `create'
Essentially, this blows up while trying to call Campaign.new with the image attributes. I thought the image field was nil but when I inspected the img_attr from the server, I noticed the uploaded file was present and the temp field was corretly pointing to a local copy.
When I dug deeper, I noticed the the cover
filed in my themed_controller was invalid.
MOPED: 127.0.0.1:27017 INSERT database=mangoweb_development collection=themed_campaigns
documents=[{"_id"=>BSON::ObjectId('53ba605c5661731da8060000'), "campaign_title"=>"Test campaign", "campaign_description"=>"Test campaign desciption", "live_story_ids"=>["53a9b3e5566173146e030000", "5343eafc5661731195030000", "5343eacc566173117f030000", "5343eadf5661731189030000"], "valid_from"=>2014-07-07 00:00:00 UTC, "valid_till"=>2014-07-22 00:00:00 UTC, "cover"=>"#", "added_by_email"=>"xxxxxxxxx", "campaign_sane_title"=>"Test-campaign", "updated_at"=>2014-07-07 08:54:52 UTC, "created_at"=>2014-07-07 08:54:52 UTC}] flags=[] COMMAND database=mangoweb_development command={:getlasterror=>1, :w=>1} runtime: 11.9600ms #
What am I doing wrong here?Why is the value of cover is a String version of the uploaded Object reference, instead of the file values, and why the Image not getting created?
I've been over this issue for the last 2 days, and have looked at various references. I know, I must be doing something very silly, but I'm not able to get it.
Please help me with this issue. Thanks in advance.
You can use form instance object to easily handle this
Change
form_for(@campaign, validate: true, :html => {:multipart => true}) do
to
form_for(@campaign, validate: true, :html => {:multipart => true}) do |f|
and use f
while referencing the form fields
%textarea.form-input{ name: "@campaign[campaign_description]", placeholder: "Campaign Description", required: "", value: ""}
should be changed to
f.text_area :campaign_description, placeholder: "Campaign Description", required: "", value: ""
and for the file field
f.file_field :cover
Let me know if that works