Загрузка файлов в Ruby on Rails с помощью формы с удаленным доступом: true

Я пытаюсь загрузить файлы, используя форму Rails, где для пульта установлено значение true. Я использую Rails 4.1.1. Допустим, моя модель - это Сообщение, и он использует JavaScript, чтобы пользователь мог легко отправлять несколько сообщений без перезагрузки страницы. Форма устанавливается так:

<%= form_for @message, url: {action: "create"}, html: {:class => "message-form", multipart: true}, remote: true do |f| %>

Пользователь может загрузить изображения с сообщением, если они хотят это сделать. MessageImage действует как вложенный атрибут в форме и объявляется следующим образом ( http://railscasts.com/episodes/196-nested-model-form-revised way):

<%= f.fields_for :message_images do |builder| %>
   <%= render 'message_image_fields', f: builder %>
   <%= link_to_add_fields "Add an image", f, :message_images %>
<% end %>

На моем контроллере действие примерно так:

if @message.save
   flash.now[:success] = "Message sent"
else
   flash.now[:alert] = "Error sending the message"
end
respond_to do |format|
   format.html { render 'new' }
   format.js { render 'new' }
end

Теперь это работает отлично, пока пользователь не отправляет изображения, но если они это делают, он использует format.html вместо format.js. Удаление format.html дает ActionController::UnknownFormat-исключение.

Теперь это очевидно связано с тем, что вы не можете отправлять файлы с удаленным значением true. Я попытался немного поискать и нашел этот драгоценный камень https://github.com/JangoSteve/remotipart, который, кажется, именно то, что я ищу. Я установил его, следуя инструкциям, но по какой-то причине он все еще не работает и выдает ActionController::UnknownFormat-исключение, если я удаляю format.html. Однако я не смог найти ни одного примера с вложенными атрибутами. Есть ли какие-либо альтернативы для этого драгоценного камня или любой другой способ исправить это, или я должен просто установить, что он отображает HTML, если пользователь отправляет файлы?

1 ответ

JQuery

Я не знаю, как получить вложенный модельный аспект этого, но мы уже делали загрузку файлов с помощью JQuery / asynchronicity до этого (зарегистрируйтесь, войдите в профиль):

Мы использовали jquery-file-upload gem - в основном позволяет передавать файлы через Ajax на серверную часть вашего контроллера. Чтобы дать вам четкое представление о том, как мы это сделали:

-

Код

#app/assets/javascripts/application.js
$('#avatar').fileupload({

    url: '/profile/' + $(this).attr('data_id'),
    dataType: 'json',
    type: 'post',

    add: function (e, data) {
        $(this).avatar_loading('avatar_loading');
        data.submit();
    },
    success: function (data, status) {;
        $("#avatar_img").fadeOut('fast', function() {
            $(this).attr("src", data.avatar_url).fadeIn('fast', function(){
                $(this).avatar_loading('avatar_loading');
            });
        });
    }

});


#app/views/users/index.html.erb
<%= form_for :upload, :html => {:multipart => true, :id => "avatar"}, :method => :put, url: profile_path(current_user.id), "data_id" => current_user.id do |f| %>
    <div class="btn btn-success fileinput-button avatar" id="avatar_container">
            <%= f.file_field :avatar, :title => "Upload New" %>
            <%= image_tag(@user.profile.avatar.url, :width=> '100%', :id => "avatar_img", :alt => name?(@user)) %>
    </div>
<% end %>


#app/controllers/profile_controller.rb
Class ProfileController < ApplicationController
   def update
       def update
        @profile = User.find(current_user.id)
        @profile.profile.update(upload_params)

        respond_to do |format|
            format.html { render :nothing => true }
            format.js   { render :partial => 'profiles/update.js' }
            format.json { 
                render :json => @profile.profile.as_json(:only => [:id, :avatar], :methods => [:avatar_url])
            }
        end

        def upload_params
            params.require(:upload).permit(:avatar, :public, :description)
        end
   end
end

-

Реализация

Для вашей реализации я бы рекомендовал сначала создать сообщение, а затем заставить пользователя добавить к нему несколько изображений в другом действии.

После того, как у вас это получится, вы можете заставить его работать как одна форма

Другие вопросы по тегам