嵌套的属性图像上载未更新(Rails 4 / Carrierwave)

时间:2014-07-16 15:22:16

标签: ruby-on-rails carrierwave

我使用此示例使用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)

1 个答案:

答案 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是一个很棒的宝石,可以帮助您轻松地在表单中嵌入嵌套属性。