Ruby on rails issue with Paperclip while uploading to s3
Asked Answered
R

2

8

I have a record model and controller:

require 'open-uri'
class Record < ActiveRecord::Base

  has_attached_file :record,
                    :s3_protocol => :https,
                    :url => ':s3_domain_url',
                    :path => '/record/latest/:basename.:extension'

  has_attached_file :archive_record,
                    :s3_protocol => :https,
                    :url => ':s3_domain_url',
                    :path => '/record/archive/:basename.:extension'
end


class RecordsController < ApplicationController
  def upload_record
    @error = nil
    previous_record = Record.where(:is_archive => false).first
    @new_record = Record.new(record_params)
    if @new_record.save
      unless previous_record.blank?
        if create_archive(previous_record)
          previous_record.destroy
        end
      end
      @success = I18n.t('record.success.record_uploaded')
    else
      @error = find_error(@new_record)
    end

    respond_to do |format|
      format.js {
        render :layout => false
      }
    end
  end 

  def change_record
    previous_record = Record.where(:is_archive => false).first
    archive_record = Record.where(:id => params[:id]).first
    if create_archive(previous_record) && create_current(archive_record)
      previous_record.destroy
      archive_record.destroy
    end
  end

  private

  def record_params
    params.require(:record).permit(:record_type, :record, :version, :release_date)
  end

  def create_archive(previous_record)
    archive = Record.new
    archive.archive_record = URI.parse(previous_record.record.url)
    archive.version = previous_record.version
    archive.record_file_name = previous_record.record_file_name
    archive.record_content_type = previous_record.record_content_type
    archive.is_archive = true
    @archive_record_remote_url = previous_record.record.url
    archive.save(:validate => false)
  end

  def create_current(archive_record)
    latest = Record.new
    latest.record = URI.parse(archive_record.archive_record.url)
    latest.version = archive_record.version
    latest.record_file_name = archive_record.record_file_name
    latest.record_content_type = archive_record.record_content_type
    latest.is_archive = false
    @archive_record_remote_url = archive_record.archive_record.url
    latest.save(:validate => false)
  end
end

There are two attached files: the latest record and the archive.

The method upload_record uploads a record and checks that if there is any other record present in the latest record (latest record can only be one record and archive can have many). When there is an existing record in latest or we can say if there is a current record, the method create_archive is called which converts the latest record to an archive record and saves it into the archive folder in s3. The newly uploaded record becomes the current record.

There is a method change_record which is called when a 'make current' button on any of the archives is clicked. In the change_record method I turn the latest record into an archive and the clicked archive into the latest record using the two methods create_archive and create_current.

When I convert any record to an archive_record it is successfully doing it and I am able able to see the record is saved in /record/archive/ in S3 but when I convert the archive record to current record the record is not getting saved in /record/latest/ in S3.

Thank you for reading this long problem. Can someone help me out?

Rexer answered 18/9, 2015 at 10:31 Comment(5)
You say it's not saved in /record/archive when you make it current but you would expect it to be saved in /record/latest. Not sure if this is a typo or the beginnings of the explanation of the problem.Aulic
i am sorry ... editedRexer
@Rexer I edited your post for spelling / grammar. Could you double-check it still makes sense like you intended? ;)Sine
First of all, I don't understand why you are using URI.parse and if you are parsing it then you don't have to assign paperclip default variables. It seems like you want dump previous files? Am I right?Laski
latest.record = archive_record.archive_record...this would do the trickLaski
L
1

I did some deep cloning of paperclip record in my project and too faced issues with URI.parse, I simply dumped existing paperclip record and it worked fine. Well in your case, this should work fine

def create_archive(previous_record)
  archive = Record.new
  archive.archive_record = previous_record.record
  archive.version = previous_record.version
  archive.is_archive = true
  @archive_record_remote_url = previous_record.record.url
  archive.save(:validate => false)
end

def create_current(archive_record)
  latest = Record.new
  latest.record = archive_record.archive_record
  latest.version = archive_record.version
  latest.is_archive = false
  @archive_record_remote_url = archive_record.archive_record.url
  latest.save(:validate => false)
end
Laski answered 26/2, 2016 at 7:45 Comment(0)
N
0

I've tried the same thing using paperclip, but it was little complicated.

So i preferred using the rails itself to upload files and retrieve it,

It can be done by,

<%= f.file_field :file_name %>   
<div class="actions">
<%= f.submit "Upload" %>   
</div>

It can be retrieved by,

File.open(Rails.root.join( 'app/assets/images/', memory.original_filename), 'wb') do |file|
     file.write(memory.read)
end
Nikolaus answered 26/2, 2016 at 7:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.