我正试着让这个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"
答案 0 :(得分:1)
而不是使用jquery文件上传只需尝试使用remotepart gem,这将使我们的rails远程表单携带该文件。请参阅http://os.alfajango.com/remotipart/。