我使用此示例使用Carrierwave Rails 4 multiple image or file upload using carrierwave创建多个图片上传。出于某种原因,如果我编辑帖子并尝试上传其他图片,则不会更新。
listings_controller.rb
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :except => [:show, :index]
def index
@listings = Listing.order('created_at DESC')
respond_to do |format|
format.html
format.json { render json: @listings }
end
end
def show
@image_attachments = @listing.image_attachments.all
end
def new
@listing = Listing.new
@listing.user = current_user
@image_attachment = @listing.image_attachments.build
end
def edit
end
def create
@listing = Listing.new(listing_params)
@listing.created_at = Time.now
@listing.user = current_user
respond_to do |format|
if @listing.save
params[:image_attachments]['image'].each do |a|
@image_attachment = @listing.image_attachments.create!(:image => a, :listing_id => @listing.id)
end
format.html { redirect_to @listing, notice: 'Post was successfully created.' }
else
format.html { render action: 'new' }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @listing.update(listing_params)
flash[:notice] = 'Deal was successfully updated.'
format.html { redirect_to @listing }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
def destroy
@listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
@listing = Listing.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:condition, :listing_title, :nickname, :listing_size, :listing_price, :user_id, image_attachments_attributes: [:id, :listing_id, :image])
end
end
列表表格
<%= form_for(@listing, :html => { :class => 'form', :multipart => true }) do |f| %>
<% if @listing.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@listing.errors.count, "error") %> prohibited this listing from being saved:</h2>
<ul>
<% @listing.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.fields_for :image_attachments do |p| %>
<div>
<%= p.label :image %>
<%= p.file_field :image, :multiple => true, name: "image_attachments[image][]", :class => 'upload' %>
</div>
<% end %>
<div class="actions">
<%= f.submit 'Submit', :class => 'submitButton' %>
</div>
<% end %>
listing.rb
has_many :image_attachments
accepts_nested_attributes_for :image_attachments
有任何帮助吗?感谢。
更新
这是我尝试更新图像字段时的日志输出。 &#34; about.png&#34;是我试图上传的新图片。
Started PATCH "/listings/nike-air-max-90" for 127.0.0.1 at 2014-07-16 11:40:14 -0400
Processing by ListingsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LU1ADy5JqfuX9CMDtcG/dmGgu9nuvplDQrVixfICsS4=", "listing"=>{"listing_title"=>"Nike Air Max 90", "nickname"=>"", "listing_size"=>"9.5", "listing_price"=>"160", "image_attachments_attributes"=>{"0"=>{"id"=>"1"}}}, "image_attachments"=>{"image"=>[#<ActionDispatch::Http::UploadedFile:0x00000109506810 @tempfile=#<Tempfile:/var/folders/vk/x5f3g8n147z_j39_mzkbfq600000gp/T/RackMultipart20140716-1370-63vlgx>, @original_filename="about.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"image_attachments[image][]\"; filename=\"about.png\"\r\nContent-Type: image/png\r\n">]}, "commit"=>"Submit", "id"=>"nike-air-max-90"}
[1m[35mListing Load (0.2ms)[0m SELECT "listings".* FROM "listings" WHERE "listings"."slug" = 'nike-air-max-90' ORDER BY "listings"."id" ASC LIMIT 1
[1m[36mUser Load (0.2ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1[0m
[1m[35m (0.1ms)[0m begin transaction
[1m[36mImageAttachment Load (0.1ms)[0m [1mSELECT "image_attachments".* FROM "image_attachments" WHERE "image_attachments"."listing_id" = ? AND "image_attachments"."id" IN (1)[0m [["listing_id", 2]]
[1m[35m (0.1ms)[0m commit transaction
Redirected to http://localhost:3000/listings/nike-air-max-90
Completed 302 Found in 5ms (ActiveRecord: 0.6ms)
答案 0 :(得分:0)
选项1(将所有现有附件替换为新上传的附件
在update
行动中,您没有按照create
行动做您正在做的事情。这是:
params[:image_attachments]['image'].each do |a|
@image_attachment = @listing.image_attachments.create!(:image => a, :listing_id => @listing.id)
end
你不能指望Rails神奇地为你做这件事,因为这不是accepts_nested_attributes
功能的典型用法。实际上,在您当前的代码中,您根本就没有使用此功能。
如果您想使其与当前代码一起使用,则必须删除所有现有image_attachments
并在update
操作中创建新代码,如下所示:
def update
respond_to do |format|
if @listing.update(listing_params)
if params[:image_attachments] && params[:image_attachments]['image']
# delete existing image_attachments
@listing.image_attachments.delete_all
# create new ones from incoming params
params[:image_attachments]['image'].each do |a|
@image_attachment = @listing.image_attachments.create!(:image => a, :listing_id => @listing.id)
end
end
flash[:notice] = 'Deal was successfully updated.'
format.html { redirect_to @listing }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @listing.errors, status: :unprocessable_entity }
end
end
end
如果您上传新图片,这将用新图片替换所有现有图片。
选项2(单独编辑)
如果您希望能够更新现有附件,则必须修改编辑表单以允许单独更新附件记录。或者通过正确使用accepts_nested_attributes
功能来实现。 Cocoon是一个很棒的宝石,可以帮助您轻松地在表单中嵌入嵌套属性。