简体   繁体   中英

Refresh page after file upload with CarrierWave on Rails

I'm developing an application which uses CarrierWave as file manager (upload and download). It's used on my project model. It's kinda working because it upload the file but it doesn't refresh page nor show errors if there is any (but showed in the console -- whitelist error), in the other case (detroy) it shows the message correctly. I'll be really appreciated if you guys help me because i tested several things (redirect to root, etc) and nothing happens.

Project.rb

class Project < ApplicationRecord

  mount_uploaders :attachments, AttachmentUploader # Tells raisl to use this uploader with this model
  serialize :attachments, JSON # If you use SQLite, add this line.

end

attachments_controller.rb

class AttachmentsController < ApplicationController
    before_action :set_project

    def create
        add_more_attachments(attachments_params[:attachments])

            respond_to do |format|
          if @project.save
            format.html { redirect_to project_path(@project), notice: 'Archivo fue subido existosamente.' }

          else
            format.html { render partial: 'projects/uploads/new' }

            format.json { render json: @project.errors, status: :unprocessable_entity }

          end
            end

    end

    def download
        path = "uploads/#{params[:id]}/#{params[:basename]}.#{params[:extension]}"
        send_file path, :x_sendfile=>true
    end

    def destroy
        remove_attachments_at_index(params[:id].to_i) 
        respond_to do |format|
            format.html { redirect_to project_path(@project), notice: 'Archivo fue eliminado existosamente.' }
        end
    end

    private

    def set_project
        @project = Project.find_by_id(params[:project_id])
    end

    def add_more_attachments(new_attachments)
        attachments = @project.attachments # copy the old images 
        attachments += new_attachments # concat old images with new ones
        @project.attachments = attachments # assign back
    end

    def remove_attachments_at_index(index)
        if @project.attachments.count == 1
            #truco para remover ultimo elemento
            @project.remove_attachments!
        else
            remain_attachments = @project.attachments # copy the array
            deleted_attachment = remain_attachments.delete_at(index) # delete the target image
            @project.attachments = remain_attachments # re-assign back
        end
        @project.save
    end

    def attachments_params
    params.require(:project).permit({attachments: []}) # allow nested params as array
    end
end

Projects#Show (where i upload and remove files)

<div class="medium-8 columns">
    <h3>
        Archivos
    </h3>
    <ul> 
        <% if @project.attachments.present? %>
            <% @project.attachments.each_with_index do |attachment,index| %>
                <li>
                    <%= link_to "Descargar #{attachment.file.filename}", "/uploads/#{@project.id}/#{File.basename(attachment.url)}"%>

                </li>
                <%= link_to "Eliminar", project_attachment_path(@project, index), :method => :delete, data: { confirm: "¿Está seguro de eliminar este archivo?" } %>
            <% end %>
        <% end %>
    </ul>  
    <%= render(:partial => 'projects/uploads/new') %>   

</div>

_new.html.erb (attachment form)

<div class="">
  <%= form_with(model: @project, :html => {multipart: true}, url: project_attachments_path(@project), method: :post)  do |form| %>

    <% if @project.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:</h2>
      <ul>
      <% @project.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

    <%= form.label :attachments %>
    <%= form.file_field :attachments, multiple: true %>
    <%= form.submit "Subir", :class => "button" %>
  <% end %>
</div>

Console output

Started POST "/projects/3/attachments" for 127.0.0.1 at 2018-03-25 11:51:26 -0300
Processing by AttachmentsController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"LW7yFaDtZqPSglxM8TSHy2FLBPIrhSl8Gn9rOkZheOWPlj6QDrGOPATlYOj2uQ5exMHp+T+iPbB8lehjY/IzqA==", "project"=>{"attachments"=>[#<ActionDispatch::Http::UploadedFile:0x007fecafc5b900 @tempfile=#<Tempfile:/tmp/RackMultipart20180325-24920-hgufys.pdf>, @original_filename="CAMBIO_ACUMULADOR_RADISSON(1).pdf", @content_type="application/pdf", @headers="Content-Disposition: form-data; name=\"project[attachments][]\"; filename=\"CAMBIO_ACUMULADOR_RADISSON(1).pdf\"\r\nContent-Type: application/pdf\r\n">]}, "commit"=>"Subir", "project_id"=>"3"}
  Project Load (0.4ms)  SELECT  `projects`.* FROM `projects` WHERE `projects`.`id` = 3 LIMIT 1
   (0.2ms)  BEGIN
  Estimate Load (0.4ms)  SELECT  `estimates`.* FROM `estimates` WHERE `estimates`.`id` = 3 LIMIT 1
  SQL (0.6ms)  UPDATE `projects` SET `attachments` = '[\"CV_Rodrigo_Cordova.pdf\",\"CAMBIO_ACUMULADOR_RADISSON_1_.pdf\"]', `updated_at` = '2018-03-25 11:51:26' WHERE `projects`.`id` = 3
   (2.1ms)  COMMIT
Redirected to http://localhost:3000/projects/3
Completed 302 Found in 16ms (ActiveRecord: 3.7ms)

And then... start get but no difference in browser, except when i refresh manually

Started GET "/projects/3" for 127.0.0.1 at 2018-03-25 11:51:26 -0300
Processing by ProjectsController#show as JS
  Parameters: {"id"=>"3"}
  Project Load (0.5ms)  SELECT  `projects`.* FROM `projects` WHERE `projects`.`id` = 3 LIMIT 1
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
  User Load (0.5ms)  SELECT `users`.* FROM `users` INNER JOIN `projects_users` ON `users`.`id` = `projects_users`.`user_id` WHERE `projects_users`.`project_id` = 3
  Rendering projects/show.html.erb within layouts/application
  Estimate Load (0.4ms)  SELECT  `estimates`.* FROM `estimates` WHERE `estimates`.`id` = 3 LIMIT 1
   (0.4ms)  SELECT COUNT(*) FROM `tasks` WHERE `tasks`.`project_id` = 3 AND `tasks`.`status` = 0
   (0.4ms)  SELECT COUNT(*) FROM `tasks` WHERE `tasks`.`project_id` = 3 AND `tasks`.`status` = 1
   (0.4ms)  SELECT COUNT(*) FROM `tasks` WHERE `tasks`.`project_id` = 3 AND `tasks`.`status` = 2
   (0.3ms)  SELECT COUNT(*) FROM `tasks` WHERE `tasks`.`project_id` = 3 AND `tasks`.`status` = 3
  Rendered projects/uploads/_new.html.erb (1.9ms)
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Rendered projects/show.html.erb within layouts/application (15.3ms)
  Rendered layouts/_navigation_links.html.erb (0.4ms)
  Rendered layouts/_nav_links_for_auth.html.erb (1.1ms)
  Rendered layouts/_navigation.html.erb (9.8ms)
  Rendered layouts/_messages.html.erb (0.4ms)
  Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 139ms (Views: 124.5ms | ActiveRecord: 3.7ms)

EDIT :

Submit button but no change on listed files

刷新之前

Manually refresh (it works!)

刷新后

Thanks in advance.

where is your image div?

<div class="medium-8 columns">
    <h3>
        Archivos
    </h3>
    <ul> 
        <% if @project.attachments.present? %>
            <% @project.attachments.each_with_index do |attachment,index| %>
                <li>
                    <%= link_to "Descargar #{attachment.file.filename}", "/uploads/#{@project.id}/#{File.basename(attachment.url)}"%>

                </li>
                <%= link_to "Eliminar", project_attachment_path(@project, index), :method => :delete, data: { confirm: "¿Está seguro de eliminar este archivo?" } %>
            <% end %>
        <% end %>
    </ul>  
    <%= render(:partial => 'projects/uploads/new') %>   

</div>

something like this

<%= image_tag attachment.url %>

but you say it works on refesh?

I found the solution. The form was being submitted by ajax.

So i had to add to my form local: true parameter, like this:

<%= form_with(model: @project,local: true, :html => {multipart: true}, url: project_attachments_path(@project), method: :post)  do |form| %>
...
<% end %>

And works like a charm. Thanks to the readers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM