【问题标题】:Ruby on Rails file uploading using a form with remote: true使用远程表单上传 Ruby on Rails 文件:true
【发布时间】:2014-07-17 07:45:24
【问题描述】:

我正在尝试使用远程设置为 true 的 Rails 表单上传文件。我正在使用 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 方式):

<%= 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-exception。

现在,这显然与您无法提交远程设置为 true 的文件有关。我试着搜索了一下,发现了这颗宝石 https://github.com/JangoSteve/remotipart ,这似乎正是我要找的。我按照说明安装了它,但由于某种原因,如果我删除 format.html,它仍然无法工作并给出 ActionController::UnknownFormat-exception。但是,我找不到任何涉及嵌套属性的示例。这个 gem 是否有任何替代方法或任何其他方法来解决这个问题,或者我应该设置它在用户提交文件时呈现 HTML?

【问题讨论】:

    标签: javascript ruby-on-rails forms remotipart


    【解决方案1】:

    JQuery

    我不知道如何获得这方面的嵌套模型,但我们已经在here 之前使用 JQuery / 异步完成了文件上传(注册帐户,登录个人资料):

    我们使用了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
    

    --

    实施

    对于您的实现,我建议首先创建消息,然后让用户在另一个操作中将一些图像附加到它

    完成该工作后,您可以将其作为一种形式工作

    【讨论】:

    • 谢谢,我会检查一下。问题是当用户上传图片时,还没有 Message 类的实例。一种可能性可能是渲染 .js.erb 并使用 AJAX 发送图像,因为那里有一个可用的实例,但我不知道是否有任何更清洁的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2010-11-25
    • 2011-10-20
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多