我正在疯狂地尝试让这个 jquery-fileupload 功能与carrierwave一起使用:
http://railscasts.com/episodes/381-jquery-file-upload?autoplay=true
它给我带来了各种各样的问题。我有 3 个模型 - 用于项目、版本和层。在一个项目中,我试图在同一个表单中创建一个版本和几个关联的层(来自视图/版本中的 new.html.erb 文件)。我正在关注 Ryan Bates Railscast #381,当直接在新视图中选择时,似乎无法自动上传文件。(在新版本页面上,如果我选择多个图层文件然后单击“创建版本”按钮,关联的图层文件会成功上传。但在教程中,当通过 jquery 选择时它们会立即上传,而无需单击任何“创建”按钮。他所做的和我正在尝试做的主要区别是他正在从“绘画”索引页面上传所有文件......
我希望这是有道理的......我的代码如下,但如果我应该提供进一步的解释,请告诉我。(我已经搜索了很多问题,但我的示例似乎比我遇到的大多数“单模型”jquery-fileupload 示例更复杂)。
宝石文件
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'
路线.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(版本模型)
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(层控制器)
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(图层模型)
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 部分)
<li>
<div class="bg-add">
<%= layer.audio %>
</div>
</li>
APPLICATION.JS(资产/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(应用程序/资产/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"