如何使用Carrierwave在Rails 4中上传多个图像 - 不会发生上传

时间:2016-07-26 10:34:55

标签: ruby-on-rails ruby-on-rails-4 carrierwave

我正在研究产品目录 - 每个项目(型号:项目)都有很多图像(型号:ItemImage)。对于图像上传,我使用Carrierwave gem。提交带有Item属性的表单后,我看到除了图像ulpoad之外所有文本/选择字段都正常工作 - 我在“show”页面上看不到任何图片,在ActiveRecord中没有新的ItemImages。

我认为form_for使用item属性正确生成所有查询,但item_controller不保存“item_images_attributes”中的数据。

我该如何解决这个问题?

更新

我在表单提交后错过了一个错误 - “无法使用MiniMagick进行操作,也许它不是图像?原始错误:未安装ImageMagick / GraphicsMagick”“

#<ActiveModel::Errors:0x007f9982a5a690 @base=#<...>, @messages=  {:"item_images.image"=>["Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: ImageMagick/GraphicsMagick is not installed"]}>

没有mini_magick gem的所有工作 - 问题出在mini_magick安装中。

我使用Rails 4.2.6 + carrierwave 0.11.2 + mini_magick 4.5.1

查询,上传2张图片:

Started PATCH "/items/15" for ::1 at 2016-07-26 12:35:27 +0300
Processing by ItemsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fIcV7MQgCcca1E31bGC3R1ESPTLqfIgjowmIvygYyuodp1gHtkjbEBwYJ0NPMhAZk0mRxDH1xuvqmUOx9cL19g==", "item"=>{"name"=>"porsche 911 turbo", "category_ids"=>["1",""], "item_images_attributes"=>{"0"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007f99846708c0 @tempfile=#<Tempfile:/var/folders/3m/522lw46j5rngq0gdp86r4_4c0000gn/T/RackMultipart20160726-58459-9jljsv.jpg>, @original_filename="0_21058_e8ca3262_L.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"item[item_images_attributes][0][image]\"; filename=\"0_21058_e8ca3262_L.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "1"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007f99846707a8 @tempfile=#<Tempfile:/var/folders/3m/522lw46j5rngq0gdp86r4_4c0000gn/T/RackMultipart20160726-58459-1eikktq.jpg>, @original_filename="0_57202_48ad8d07_XL.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"item[item_images_attributes][1][image]\"; filename=\"0_57202_48ad8d07_XL.jpg\"\r\nContent-Type: image/jpeg\r\n">}}}, "commit"=>"Сохранить изменения!", "id"=>"15"}

视图

视图/项目/ new.html.haml

%h1 Create new item

= form_for(@item, html: { multipart: true }) do |f|
    = render partial: "layouts/item_form", locals: {f: f}
    = f.submit 'Create item!'
%p
    = link_to "All items", items_path

视图/项目/ edit.html.haml

%h1 Edit item:

= form_for(@item, html: { multipart: true }) do |f|
    = render partial: "layouts/item_form", locals: {f: f}
    = f.submit 'Save changes!'
%p
    = link_to "link to item page", item_path(@item)
%p
    = link_to "link to catalog", items_path(@item)

视图/布局/ _item_form.html.haml

= f.label :name, "Item name"
= f.text_field :name 

= f.label :category_ids, 'Category'
= collection_check_boxes :item, :category_ids, Category.all, :id, :name

= f.fields_for :item_images do |item_image|
   - if item_image.object.new_record?
       = item_image.file_field :image
   - else
       = image_tag(item_image.object.image.url(:thumb))
       = item_image.check_box :_destroy

视图/项目/ show.html.haml

%h1 
    = @item.name
%p
    categories:
    - @item.categories.each do |j|
        = j.name
.input-gr
    = form_for @position, remote: true do |f|
        = f.hidden_field :quantity, value: 1
        = f.hidden_field :item_id, value: @item.id
        = f.submit "Add to cart", class: "btn btn-primary" 
%p
    = link_to "Edit item", edit_item_path(@item)
%p
    = link_to "All items", items_path

型号:

item.rb的

class Item < ActiveRecord::Base
    has_many :item_images
    accepts_nested_attributes_for :item_images, :allow_destroy => true, reject_if: proc { |attributes| attributes[:image].blank? }
    ...
end

item_image.rb

class ItemImage < ActiveRecord::Base
    mount_uploader :image, ImageUploader 
    belongs_to :item
    ...
end

控制器:

items_controller.rb

before_filter :find_item, only: [:show, :edit, :update, :destroy]

def new
    @item=Item.new
    3.times { @item.item_images.build }
end

def create
    @item=Item.create(item_params)

    if @item.errors.empty?
        redirect_to item_path(@item)
    else
        render "new"
    end
end

def show
    @position=current_cart.positions.new
    @images=@item.item_images
end

def edit
    3.times { @item.item_images.build }
end

def update
    @item.update_attributes(item_params)
    if @item.errors.empty?
        redirect_to item_path(@item)
    else
        render "edit"
    end
end

def destroy
    @item.destroy
    redirect_to items_path
end

def index
    @items=Item.all
    @position_new=current_cart.positions.new

end


private
    def find_item
        @item=Item.find(params[:id])
    end
    def item_params
        params.require(:item).permit(:name, :price, category_ids: [], item_images_attributes: [:id, :item_id, :image])
    end

的ActiveRecord ::模式

ActiveRecord::Schema.define(version: 20160725185204) do

  ...

  create_table "item_images", force: :cascade do |t|
    t.string   "image"
    t.string   "item_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "items", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string   "name"
    ...

  end

  ...

end

上传

上传/ image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base

  include CarrierWave::MiniMagick

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :thumb do
    process :resize_to_fit => [236, 236]
  end
  version :medium do
    process :resize_to_fit => [500, 500]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end

0 个答案:

没有答案