У меня есть модель для лошадей и фотомодель. Я использую загрузку файла jQuery для изменения размера (на стороне клиента) изображений и сохранения на Amazon s3 напрямую, так как я использую Heroku.jQuery Загрузка файла в Rails 4.x Вложенная форма
Я видел другие вопросы, подобные тем, которые используют несущую волну, скрепку или очень старые. Я не уверен, почему вы будете использовать carrierwave/paperclip, но я думаю, что, основываясь на том, что говорит героику, я не хочу, чтобы изображения попадали в сервер, потенциально вызывая тайм-ауты.
Heroku recommends с использованием загрузки файла jQuery и показывает js, добавляющий новый ввод файла со значением ссылки изображения (возвращенной с amazon s3). У меня это работает при сохранении фотографии отдельно. Теперь я хочу заставить его работать в вложенной форме для Лошади, но js не находит вход (поскольку он еще не существует, потому что он вложен, я полагаю).
Я использую Cocoon для вложенных форм (я открыт для всего, что будет работать лучше). Я не слишком хорошо знаком с javascript/jQuery, но, насколько я могу судить, Cocoon «скрывает» вложенный элемент, пока я не нажму, чтобы добавить его через add_association.
Haml код вид:
= link_to_add_association 'add photo', f, :photos
HTML источник перед нажатием кнопки 'Добавить фотографию'
<div class='links'>
<a class="btn btn-default btn-sm add_fields" data-association-insertion-method="after" data-association="photo" data-associations="photos" data-association-insertion-template="<div class='nested-fields'>
<fieldset class="inputs"><ol><input type="file" name="horse[photos_attributes][new_photos][url]" id="horse_photos_attributes_new_photos_url" />
<input type="hidden" name="horse[photos_attributes][new_photos][_destroy]" id="horse_photos_attributes_new_photos__destroy" value="false" /><a class="remove_fields dynamic" href="#">remove photo</a>
</ol></fieldset>
</div>
" href="#">add photo</a>
Как работать с этим входом и как обрабатывать загрузки нескольких файлов, как они добавлены правильно?
Мои текущие загрузки JS:
$(function() {
if ($('#new_horse').length > 0) {
$.get("/presign", function(s3params) {
$('.direct-upload').find("input:file").each(function(i, elem) {
var fileInput = $(elem);
var form = $(fileInput.parents('form:first'));
var submitButton = form.find('input[type="submit"]');
var progressBar = $("<div class='bar'></div>");
var barContainer = $("<div class='progress'></div>").append(progressBar);
fileInput.fileupload({
fileInput: fileInput,
url: "http://" + s3params.url.host,
type: 'POST',
autoUpload: true,
formData: s3params.fields,
paramName: 'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
dataType: 'XML', // S3 returns XML if success_action_status is set to 201
disableImageResize: false,
imageQuality: 0.5,
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator && navigator.userAgent),
imageMaxWidth: 500,
imageMaxHeight: 1000,
imageOrientation: true, //auto rotates images
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, //I added this to jquery.fileupload-validate: alert('Must Be JPG GIF or PNG Image')
replaceFileInput: false,
progressall: function (e, data) {
var progress = parseInt(data.loaded/data.total * 100, 10);
progressBar.css('width', progress + '%')
},
start: function (e) {
submitButton.prop('disabled', true);
fileInput.after(barContainer);
progressBar.
css('background', 'green').
css('display', 'block').
css('width', '0%').
text("Loading...");
},
done: function(e, data) {
submitButton.prop('disabled', false);
progressBar.text("Pre-uploading done... Please Save or Cancel");
// extract key and generate URL from response
var key = $(data.jqXHR.responseXML).find("Key").text();
var url = 'https://' + s3params.url.host +'/' + key;
// remove first input to prevent phantom upload delay
fileInput.remove();
// create new hidden input with image url
var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url })
var imgPreview = '<img src="' + url + '">';
form.append(input);
form.append(imgPreview);
},
fail: function(e, data) {
submitButton.prop('disabled', false);
progressBar.
css("background", "red").
text("Failed");
}
});
});
}, 'json');
}
});