私はこのjquery-fileupload機能をcarrierwaveで動作させるために狂ったようにしようとしています:
http://railscasts.com/episodes/381-jquery-file-upload?autoplay=true
そしてそれは私にあらゆる種類の問題を引き起こしています。プロジェクト、バージョン、レイヤーの 3 つのモデルがあります。プロジェクト内で、同じフォーム内にバージョンといくつかの関連レイヤーの両方を作成しようとしています (ビュー/バージョンの new.html.erb ファイルから)。私は Ryan Bates Railscast #381 をフォローしていますが、新しいビューで直接選択したときにファイルを自動的にアップロードできないようです。(新しいバージョンのページで、いくつかのレイヤー ファイルを選択して [バージョンの作成] ボタンをクリックすると、関連付けられたレイヤー ファイルが正常にアップロードされます。ただし、チュートリアルでは、[作成] をクリックしなくても、jquery 経由で選択するとすぐにアップロードされます)ボタン. 彼がしていることと私がやろうとしていることの主な違いは、彼が「絵画」インデックスページからすべてのファイルをアップロードしていることです...
これが理にかなっていることを願っています...私のコードは次のとおりですが、さらに説明を提供する必要がある場合はお知らせください。(私は多くの質問を探しましたが、私の例は、私が遭遇したほとんどの「単一モデル」の 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'
ルート.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...これは CARRIERWAVE アップローダー ファイルです)
# 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 PARTIAL)
<li>
<div class="bg-add">
<%= layer.audio %>
</div>
</li>
APPLICATION.JS (アセット/JAVASCRIPT)
//= 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/JAVASCRIPT...)
# 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"