我正在研究产品目录 - 每个项目(型号:项目)都有很多图像(型号: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