Jquery-fileupload-rails不支持多部分表单

时间:2014-05-18 17:20:23

标签: ruby ruby-on-rails-4 carrierwave jquery-file-upload jquery-fileupload-rails

我正试着让这个jquery-fileupload功能与carrierwave一起工作:

http://railscasts.com/episodes/381-jquery-file-upload?autoplay=true

它给我带来了各种各样的问题。我有3个模型 - 用于项目,版本和图层。在一个项目中,我试图在同一个表单中创建一个版本和几个相关的层(来自views / versions中的new.html.erb文件)。我正在关注Ryan Bates Railscast#381,直接在新视图中选择时,似乎无法自动上传文件。 (在新版本页面上,如果我选择多个图层文件然后单击“创建版本”按钮,关联的图层文件会成功上传。但是在教程中,当通过jquery选择时,他们立即上传,而不必点击任何“创建”他正在做的事情和我正在尝试做的事情之间的主要区别是他正在上传“绘画”索引页面中的所有文件...我试图直接在'new.html上显示上传的文件.erb'表单页面...&然后当用户点击“创建版本”时,表单将同时创建新版本和新关联图层。

我希望这是有道理的......我的代码如下,但如果我应该提供进一步的解释,请告诉我。 (我已经找到了很多问题但是我的例子看起来比我遇到的大多数'单模'jquery-fileupload例子要复杂得多。)

的Gemfile

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.4'
gem 'pg'
gem 'bootstrap-sass', '3.1.1.0'
gem 'sprockets', '2.11.0'
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'
gem 'faker'
gem 'bootstrap_form'
gem 'will_paginate'
gem 'bootstrap-will_paginate'
gem "pundit"
gem 'rails3-jquery-autocomplete', :git=>'git@github.com:yangbodotnet/rails3-jquery-autocomplete.git'
gem 'jquery-fileupload-rails'
gem 'remotipart', '~> 1.2'

gem 'rmagick', :require => 'RMagick'
gem 'carrierwave'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.2'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library & jquery UI
gem 'jquery-rails'
gem 'jquery-ui-rails'

# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'

的routes.rb

ProductionApp::Application.routes.draw do

  resources :users
  resources :sessions, only: [:new, :create, :destroy]

  resources :projects do
    resources :versions
    match '/settings'=>'projects#settings', :via=>:get, :as=>:settings
    match '/collaboration'=>'projects#collaboration', :via=>:get, :as=>:collaboration
  end

  resources :versions do
    resources :users
  end

end

NEW.HTML.ERB(NEW VERSION PAGE& FORM。这会创建新版本和相关图层,作为附件上传...但是文件应该在选中后立即上传和显示...即,在用户点击“创建”之前。或者如果他们没有立即上传,我只需要他们在实际点击创建之前充当上传预览...

<% provide(:title, 'New Version') %>

<div class="row-fluid">
  <div class="col-md-5 no-pad">
    <h1>Create a new version</h1>
    <%= bootstrap_form_for @version, :html => {:multipart => true}, :url => project_versions_path, :remote => true do |f| %>

      <%= render 'shared/error_messages', object: f.object %>

    <%= f.text_field :title %>

    <%= f.hidden_field :user_id %>

    <div class="well">
      <h4>Drag your file uploads here:</h4>
      <%= image_tag("icon-large-grey.png", alt: "add files") %>

      <%= f.file_field :audio, multiple: true, name: "layer[audio][]", :required=>true %>

    </div>

    <%= f.button "Create Now! ", class: "btn btn-lg btn-primary" %>
  <% end %>
  </div>
  <div class="col-md-1 hidden-sm">
    <%= image_tag "shadow-vert.png" %>
  </div>
  <div class="col-md-6 no-pad">

  <!-- ------------ BELOW IS WHERE THE UPLOAD PREVIEWS SHOULD SHOW UP...but they are not ------------------------------------------------ -->

    <h1>Preview your changes & additions</h1>
    <div id="layers">
      <%= render @version.layers %>
    </div>
  </div>
</div>

AUDIO_UPLOADER.RB(UPLOADERS / AUDIO_UPLOADER.RB ......这是收件人上传者文件)

# encoding: utf-8

class AudioUploader < CarrierWave::Uploader::Base

  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end

VERSIONS_CONTROLLER

class VersionsController < ApplicationController
  before_action :find_project

  def new
    @version = @project.versions.build(user_id: current_user.id) 
  end

  def show
    @project = Project.find(params[:project_id]) 
    @version = Version.find(params[:id])
  end

  def index
    # @user = User.where(:id => @version.user_id) first figure out how to set user_id on new versions (its nil now)
    @versions = Version.paginate(page: params[:page])
  end

  def create
    @project = Project.find(params[:project_id])
    @version = @project.versions.build(version_params)
    if @version.save
      @version.create_layers_with_audio(layer_audio_params) if params[:layer]
      flash[:success] = "Created successfully"
      redirect_to project_path(@project)
    else
      render 'new'
    end
  end

  private

  def find_project
    @project = Project.find(params[:project_id])
  end

  def version_params
    params.require(:version).permit(:title, :project_id, :user_id)
  end

  def layer_audio_params
    params.require(:layer).require(:audio)
  end
end

VERSION.RB(VERSION MODEL)

class Version < ActiveRecord::Base
  belongs_to :project
  belongs_to :user
  has_many :layers, dependent: :destroy
  validates :title, presence: true, length: { maximum: 140 }

  default_scope -> { order('created_at DESC') }

  def create_layers_with_audio(audios)
    audios.each do |au|
      self.layers.create(:audio=>au, :project_id=> self.project_id)
    end
  end
end

LAYERS_CONTROLLER.RB(LAYERS CONTROLLER)

class LayersController < ApplicationController
  def index
    @layers = Layer.all
  end

  def new
    @layer = Layer.new
  end

  def show
    @layer = Layer.find(params[:id])
  end

  def create
    @project = Project.find(params[:project_id])
    @version = Version.find(params[:version_id])
    @layer = @version.layers.create(layer_params)
    # if @layer.save
      # flash[:success] = "Audio layers have been added successfully"
      # redirect_to @project
    # else
      # render 'new'
    # end
  end

  def update

  end

  def destroy

  end

  private

  # def layer_params
    # params.require(:layer).permit(:audio, :project_id, :version_id)
  # end
end

LAYER.RB(LAYER MODEL)

class Layer < ActiveRecord::Base
  belongs_to :project
  belongs_to :version

  validates :project_id, presence: true
  validates :version_id, presence: true
  validates :audio, presence: true

  mount_uploader :audio, AudioUploader
end

CREATE.JS.ERB(我相信这个文件可能是我错的地方!)

<% if @layer.new_record? %>
    alert("failed to upload layer: <%= j @layer.errors.full_messages.join(', ').html_safe %>");
<% else %>
    $("#layers").append("<%= j render(@layer) %>");
<% end %>

_LAYER.HTML.ERB(_LAYER PARTIAL)

<li>

  <div class="bg-add">
    <%= layer.audio %>
  </div>

</li>

APPLICATION.JS(ASSETS / JAVASCRIPTS)

//= require jquery
//= require jquery_ujs
//= require jquery.remotipart
//= require jquery-fileupload/basic
//= require jquery.ui.all
//= require autocomplete-rails
//= require bootstrap
//= require turbolinks
//= require bootstrapValidator/dist/js/bootstrapValidator.min
//= require_tree .

APPLICATION.CSS(资产/样式表)

 *= require_self
 *= require jquery.ui.all
 *= require bootstrapValidator/dist/css/bootstrapValidator.min
 *= require_tree .

VERSIONS.JS.COFFEE(APP / ASSETS / JAVASCRIPTS ......)

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
jQuery ->
  $('#new_layer').fileupload()
    dataType: "script"

LAYERS.JS.COFFEE(APP / ASSETS / JAVASCRIPTS ......不确定这个js是否应该分层或版本,因为表单创建了两个...所以我尝试包含在两者中)

# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
jQuery ->
  $('#new_layer').fileupload()
    dataType: "script"

1 个答案:

答案 0 :(得分:1)

而不是使用jquery文件上传只需尝试使用remotepart gem,这将使我们的rails远程表单携带该文件。请参阅http://os.alfajango.com/remotipart/