问题
I have a form in my project for a model Artworks
where I am using fields_for
for a resource Photo
where Artworks has_many :photos
.
The Photo
model uses paperclip to attach images.
All my forms are AJAX based, meaning the page should never be reloaded, and I shouldn't be using redirect_to
anywhere in my controllers (and I'm not).
When I include the fields_for
in my form with the paperclip file_field, if I create or update the photo when I submit the form, I get the following error:
Template is missing
Missing template artworks/show, application/show with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/david/rails/piml_artwork/app/views" * "/home/david/.rvm/gems/ruby-1.9.3-p194/gems/devise-2.1.2/app/views"
The destroy image checkbox functions as expected. Updating the rest of the details on the form and submitting it functions as expected, just returning an AJAX response and filling out the page.
My artworks controller is as follows:
class ArtworksController < ApplicationController
before_filter :load
authorize_resource
respond_to :html, :json, :js
def load
end
def show
@artwork = Artwork.find(params[:id])
end
def index
@artworks = Artwork.all
end
def new
@artwork = Artwork.new
@artwork.photos.build unless @artwork.photos.count > 0
end
def create
@artwork = Artwork.new(params[:artwork])
if @artwork.save
flash[:notice] = "Artwork saved"
@artworks = Artwork.all
respond_with @artwork
end
end
def edit
@artwork = Artwork.find(params[:id])
@artwork.photos.build unless @artwork.photos.count > 0
end
def update
@artwork = Artwork.find(params[:id])
if @artwork.update_attributes(params[:artwork])
flash[:notice] = "Artwork updated"
@artworks = Artwork.all
respond_with @artwork
end
end
def destroy
@artwork = Artwork.find(params[:id])
@artwork.destroy
flash[:notice] = "Artwork destroyed"
@artworks = Artwork.all
end
end
The form causing the strife is this:
<%= form_for( @artwork, remote: true, mutlipart: true ) do |f| %>
<%= render 'layouts/error_messages', object: f.object %>
<div id="artwork-title">TITLE: <%= f.text_field :title %></div>
<div id="artwork-title-underline"></div>
<div id="artwork-show-picture"><%= image_tag @artwork.photos.first.photo.url(:medium) unless @artwork.photos.first.new_record? %>
<div id="artwork-picture-upload">
<%= f.fields_for :photos, remote: true, multipart: true do |p| %>
<% if p.object.new_record? %>
UPLOAD PHOTO
<%= p.file_field :photo, value: 'Upload Image' %>
<% else %>
REPLACE PHOTO
<%= p.file_field :photo, value: 'Replace Image' %>
<br />
<br />
<%= p.check_box :_destroy %>
<%= p.label :_destroy, 'Delete Image' %>
<% end %>
<% end %>
</div>
</div>
<div id="artwork-public">
ARTIST<br />
<%= f.select :artist_id, Artist.select_list, include_blank: "SELECT ARTIST" %><br />
<br />
DATE OF WORK <br />
<%= f.text_field :date_of_work %><br />
<br />
<div id="artwork-modify-buttons">
<%= f.submit %>
</div>
<% end %>
My JS file for update is:
<% if !@artwork.errors.any? %>
$("#facebox .content").html("<%= escape_javascript(render(partial: "/artworks/show")) %>");
$("#artworks-col").html(" <%= escape_javascript(render(partial: "/admin/artworks_list" )) %>")
<% else %>
$("#facebox .content").html("<%= escape_javascript(render(partial: "/artworks/form")) %>");
<% end %>
回答1:
As it turns out, the issue I was having is that by design, you cannot upload files through AJAX.
After a few days of toiling with this, I found a gem that fixes it all incredibly easily; Remotipart
The entirety of what I had to do to fix it was:
- Add remotipart to my gem file
gem 'remotipart'
- Add
//= require jquery.remotipart
to my app/assets/javascripts/application.js file bundle install
That fixed it. Images are now uploading with what 'looks like' AJAX, but is actually using an iframe to do the work.
来源:https://stackoverflow.com/questions/12858528/rails-attaching-image-through-paperclip-on-nested-fields-causes-unwanted-unavo