Problem paperclip with ajax
I am reading this tutorial : http://sleekd.com/general/adding-multiple-images-to-a-rails-model-with-paperclip/ because i need Save the product images in a independent model. However when Product.create execute don´t save the data for product images model.
NOTE: I use the new pack action because i need to use ajax for create a new product.
Please I need Help.
My Code
Controllers
class Admin::PacksController < ApplicationController
def new
@pack = Pack.new
@product = Product.new
4.times {@product.product_images.build} # added this
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @pack }
end
end
def create_starred_product
product = Product.new(params[:product])
product.save
...
end
View
<% form_remote_for @product, :url => {:controller => "products", :action => "create_starred_product"}, :html => {:multipart => true} do |f| %>
<div id="content">
....#OTHER FIELDS OF PRODUCT. ITS SAVE METHOD IS OK
<div id="images-selector">
<span class="fleft">Imágenes</span><br/>
<% count = 0 %>
<% f.fields_for :product_images do |builder| %>
<% if builder.object.new_record? %>
<label>
Imagen <%= "#{count = count + 1}" %>
</label>
<%= builder.file_field :photo, :class => "textarea" -%><br/>
<% end %>
<% end %>
</div>
<p><%= f.submit "Crear" %></p>
</div>
<% end %>
Models
class Product < ActiveRecord::Base
h开发者_运维问答as_many :packs, :through => :pack_products
has_many :product_images, :dependent => :destroy
#PAPERCLIP
accepts_nested_attributes_for :product_images, :reject_if => lambda { |t| t['product_image'].blank? }
end
class ProductImage < ActiveRecord::Base
belongs_to :product
has_attached_file :photo, :url => "/:attachment/:class/:id/:style_:basename.:extension", :styles => { :medium => "300x300>", :thumb => "100x100>", :small => "30x30>" }
end
You can't upload files using AJAX, just like you said. There are, however, alternate solutions.
The common technique to accomplish this is the usage of an iframe. Have a look here, this tutorial is oriented towards attachment_fu but it'll work with paperclip as well. Uploadify is worth checking out and can also be used with paperclip on rails 2.3 and rails 3.
I found the solution together with my partner.
My error was in nested attributes form, no in Ajax.so I found the solution for to use paperclip with Ajax. Now I posted example code.
However I explain the code.
Models
Two models
Product and Product_images
I wanted that when i created a product in ajax form (each product belongs_to pack). Each product has many images in product_images model. Therefore I wanted save images too.
The code
Controller Ajax action
class ProductsController < ApplicationController
def create_starred_product
product = Product.new(params[:product])
product.save
render :update do |page|
page.replace_html 'star-product', :partial => "admin/products/star_product_name", :locals => {:star_product => product}
page.call "$j.modal.close"
end
end
end
Models
Products model
class Product < ActiveRecord::Base
has_many :packs, :through => :pack_products
has_many :product_images, :dependent => :destroy
#PAPERCLIP
accepts_nested_attributes_for :product_images#, :reject_if => lambda { |t| t['product_image'].blank? }
has_attached_file :photo, :url => "/:attachment/:class/:id/:style_:basename.:extension", :styles => { :medium => "300x300>", :thumb => "100x100>", :small => "30x30>" }
Product_images model
class ProductImage < ActiveRecord::Base
belongs_to :product
has_attached_file :photo, :url => "/:attachment/:class/:id/:style_:basename.:extension", :styles => { :medium => "300x300>", :thumb => "100x100>", :small => "30x30>" }
end
end
View popup in ajax (These is a partial)
<script type="text/javascript">
$j(document).ready(function() {
$j('#product_submit').click(function(event) {
event.preventDefault();
$j('#uploadForm').ajaxSubmit({
beforeSubmit: function(a, f, o) {
o.dataType = 'json';
},
complete: function(XMLHttpRequest, textStatus) {
// XMLHttpRequest.responseText will contain the URL of the uploaded image.
// Put it in an image element you create, or do with it what you will.
// For example, if you have an image elemtn with id "my_image", then
// $('#my_image').attr('src', XMLHttpRequest.responseText);
// Will set that image tag to display the uploaded image.
}
});
});
});
</script>
<div id="new-starred-product" class="popup clearfix">
<div id="header">Nuevo producto estrella</div>
<% remote_form_for @product, :url => {:controller => "products", :action => "create_starred_product"}, :html => {:method => :post, :id => 'uploadForm', :multipart => true} do |f| %>
<div id="content">
<label>Nombre:</label> <%= f.text_field :name, :class => "textarea" %>
<br/>
<label>Precio:</label> <%= f.text_field :price, :class => "textarea" %>
<br/>
<%#= f.file_field :photo %>
<div id="images-selector">
<% count = 0 %>
<%# f.fields_for "product_images_attributes[]", ProductImage.new do |builder| %>
<% f.fields_for :product_images, 4.times {ProductImage.new} do |builder| %>
<% if builder.object.new_record? %>
<label>
Imagen <%= "#{count = count + 1}" %>
</label>
<%= builder.file_field :photo, :class => "file-upload" -%><br />
<br/>
<% end %>
<%#= builder.text_field :testfield %>
<!--ACA VA EL CODIGO PARA IMAGENES-->
<% end %>
</div>
<br/>
<label>Descripción</label><%= f.text_area :description, :rows => 10, :class => "textarea clearfix" -%>
<br/>
<p>
<%#= f.submit "Crear" %>
<%= link_to "Crear", "#", :id => "product_submit" %>
</p>
</div>
<% end %>
</div>
I am using jquery and jquery-form plugin (search in google)
You'll find two versions of ajax upload on https://github.com/apneadiving/Pic-upload---Crop-in-Ajax.
Branch master
: it uses http://aquantum-demo.appspot.com/file-upload
Branch uploadify
: It uses Uploadify: http://www.uploadify.com/
Both have built-in Crop.
The problem Was nested attributes form.later I posted the code
Another gem to help with this issue I've just found when I've had the same problem is remotipart - Highly recommended.
精彩评论