0

写真と製品モデルがあります。写真は製品に属し、製品には多くの写真があります。また、製品は写真の_nested_attributes_を受け入れます。製品と写真の両方を同時に作成するフォームがあります。 私は素敵なサムネイルと開始キャンセルボタンを提供するjQuery-file-upload gemを使用しています。問題は、アップロードの開始ボタンをクリックすると、フォーム全体が非同期で送信されることです。

これは次の理由で問題になります。

  1. 3 枚の写真をアップロードしてアップロードを 3 回押すと、それぞれ 1 枚の写真だけで 3 つの異なる製品が作成されます。
  2. 商品の詳細を入力しない場合、写真のアップロードをクリックすると、商品の値がゼロで送信されます。

はる!

製品形態

= form_for @product,:url => products_path, :html => { id: "fileupload", multipart: true } do |f| 
    = f.text_field :name, placeholder: "Name"
    %br
    = f.text_field :price, class: "auto", data: { a_sign: "$ " }, placeholder: "Price" 
    %br
    = f.fields_for :photos do  |fp| 
      =fp.file_field :image
    %br

  .files{"data-target" => "#modal-gallery", "data-toggle" => "modal-gallery"}
  %p.button.start
    = f.submit

製品コントローラ

  def new 
    @product = Product.new
    @product.photos.build
  end



  def create
  @product = current_user.products.create(params[:product])
  @photo = Photo.new(params[:photo])
    respond_to do |format|
      if @product.save
        format.html {
          render :json => [@photo.to_jq_image].to_json,
          :content_type => 'text/html',
          :layout => false
        }
        format.json { render json: {files: [@photo.to_jq_image]}, status: :created, location: @photo }
      else
        format.html { render action: "new" }
        format.json { render json: @photo.errors, status: :unprocessable_entity }
      end
    end
  end

メソッド: to_jq_image

 def to_jq_image
   {
     "name" => read_attribute(:image_file_name),
     "size" => read_attribute(:image_file_size),
     "url" => image.url(:original),
     "delete_type" => "DELETE" 
   }
 end

コンソール出力

 SQL (1.2ms)  INSERT INTO "products" ("created_at", "name", "price", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["condition", "a good conditon"], ["created_at", Sun, 14 Jul 2013 17:58:19 UTC +00:00], ["name", "An example name"], ["price", #<BigDecimal:b2ab920,'0.125E1',18(18)>], ["updated_at", Sun, 14 Jul 2013 17:58:19 UTC +00:00], ["user_id", 6]]
Binary data inserted for `string` type on column `image_content_type`
  SQL (1.8ms)  INSERT INTO "photos" ("created_at", "image_content_type", "image_file_name", "image_file_size", "product_id", "updated_at") VALUES (?, ?, ?, ?, ?, ?)  [["created_at", Sun, 14 Jul 2013 17:58:19 UTC +00:00], ["image_content_type", "image/jpeg"], ["image_file_name", "DWadeCrop.jpg"], ["image_file_size", 97742], ["product_id", 140], ["updated_at", Sun, 14 Jul 2013 17:58:19 UTC +00:00]]
   (317.0ms)  commit transaction
   (0.1ms)  begin transaction
   (0.1ms)  commit transaction
Completed 201 Created in 849ms (Views: 2.4ms | ActiveRecord: 320.6ms)

製品 && 写真モデル

  class Product < ActiveRecord::Base
  attr_accessible :description, :name, :price, :photo, :photos_attributes
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos, allow_destroy: true

  include Rails.application.routes.url_helpers

  belongs_to :user

  validates :user_id, presence: true
  validates :name, presence: true, length:  { minimum: 5 }
  validates :price, presence: true
  validates :description, presence: true, length:  { minimum: 5 }

end

class Photo < ActiveRecord::Base
  attr_accessible :image
  has_attached_file :image

  include Rails.application.routes.url_helpers

  belongs_to :product
    validates_attachment :image, presence: true,
      content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'] },
      size: { less_than: 5.megabytes }
    has_attached_file :image, styles: { medium: "320x240>", :thumb => "100x100>"}

end
4

1 に答える 1

1

あなたのやり方を忘れてください。代わりに、フォームを分割し、写真作成フォームを一番上に置き、送信ボタンを削除する必要があります。次に、製品の作成が発生すると、ユーザーが更新し、現在の製品 ID に関連付けられていないすべての写真を探します。

新商品ページ

= form_for @photo, :html => { :multipart => true, :id => "fileupload"  } do |f|
  %span Add files...
    = f.file_field :image
%br
= form_for @product,:url => products_path, :html => { id: "fileupload", multipart: true } do |f| 
  %p
    = f.text_field :name, placeholder: "Name"
  %p
    = f.text_field :price, class: "auto", data: { a_sign: "$ " }, placeholder: "Price" 
  %p.button.start
    = f.submit

製品コントローラ

  def new 
    Photo.where(:product_id => nil, :user_id => current_user).delete_all
    @product = Product.new
    @photo = Photo.new
    raise "foo"
  end

  def create
  @product = current_user.products.create(params[:product])
    if @product.save
      Photo.where(:product_id => nil, :user_id => current_user).update_all(:product_id => @product.id) 
      render "show", notice: "Product created!"
    else
      render "new", error: "Error submitting product"
    end
  end

フォトコントローラー

def create
  @photo = Photo.new(params[:photo])
    respond_to do |format|
      @photo.user_id = current_user.id
      if @photo.save
        format.html {
          render :json => [@photo.to_jq_image].to_json,
          :content_type => 'text/html',
          :layout => false
        }
        format.json { render json: {files: [@photo.to_jq_image]}, status: :created, location: @photo }
      else
        format.html { render action: "new" }
        format.json { render json: @photo.errors, status: :unprocessable_entity }
      end
    end
  end
于 2013-07-15T20:11:44.043 に答える