#ruby-on-rails #carrierwave #http-upload
#ruby-on-rails #carrierwave #http-загрузка
Вопрос:
Я пытаюсь загрузить файл изображения на свой rails-сервер, но продолжаю натыкаться на стену.
Это моя форма 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
И это мой метод создания
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
Я создал отдельный загрузчик для этого,
# 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
И это моя модальная кампания, в которой хранится изображение
class Campaign
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Paranoia
include Rails.application.routes.url_helpers
mount_uploader :cover, CampaignUploader
end
Теперь, когда я загружаю форму, я продолжаю получать undefined method
empty?’ для #
> 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'
По сути, это приводит к сбою при попытке вызвать Campaign.новый с атрибутами изображения. Я думал, что поле изображения равно нулю, но когда я проверил img_attr с сервера, я заметил, что загруженный файл присутствовал, а поле temp, соответственно, указывало на локальную копию.
Когда я копнул глубже, я заметил, что cover
файл в моем themed_controller был недействительным.
MOPED: 127.0.0.1:27017 INSERT database=mangoweb_development collection=themed_campaigns
documents=[{«_id»=>BSON::ObjectId(’53ba605c5661731da8060000′),
«campaign_title»=> «Тестовая кампания», «campaign_description»=>»Тест
описание кампании», «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}] флаги=[]
КОМАНДА database=команда mangoweb_development={:getlasterror=>1, :w=>1}
время выполнения: 11.9600мс
#
Что я здесь делаю не так?Почему значение cover является строковой версией ссылки на загруженный объект, а не значениями файла, и почему изображение не создается?
Я занимался этой проблемой последние 2 дня и просмотрел различные ссылки. Я знаю, я, должно быть, делаю что-то очень глупое, но я не могу этого получить.
Пожалуйста, помогите мне с этой проблемой. Заранее спасибо.
Ответ №1:
Вы можете использовать объект экземпляра формы, чтобы легко справиться с этим
Изменить
form_for(@campaign, validate: true, :html => {:multipart => true}) do
Для
form_for(@campaign, validate: true, :html => {:multipart => true}) do |f|
и используем f
при обращении к полям формы
%textarea.form-input{ name: "@campaign[campaign_description]", placeholder: "Campaign Description", required: "", value: ""}
следует изменить на
f.text_area :campaign_description, placeholder: "Campaign Description", required: "", value: ""
и для поля file
f.file_field :cover
Дайте мне знать, если это сработает
Комментарии:
1. Спасибо за автономную поддержку. Проблема была в моем модальном. Я совершенно забыл об определении встроенной связи. Как только я это сделал, все заработало нормально. Еще раз спасибо за поддержку.