代码之家  ›  专栏  ›  技术社区  ›  Corith Malin

Ruby:回形针、S3和深度克隆

  •  4
  • Corith Malin  · 技术社区  · 14 年前

    我所拥有的是一个主题模型,它包含许多资产。资产使用回形针并将其文件内容存储在我的Amazon AWS-S3系统中。我也在使用Deep_Clone,因为我的客户能够复制内置主题,然后将其修改为心形内容。所有的deep-clone功能都很好,但是当我deep-clone资产时,旧的文件内容不会添加到我的S3存储桶中。记录会保存到数据库中,但由于文件内容没有用新的ID保存,因此file.url属性指向一个死文件。

    我试过手动调用Paperclip的“保存和创建”方法,但我无法找到如何让Paperclip将文件“推”回bucket,因为它现在有了新的ID等等。

    require 'open-uri'
    
    class Asset < ActiveRecord::Base
      belongs_to :theme
      attr_accessor :old_id
      has_attached_file :file,
                        :storage => "s3",
                        :s3_credentials => YAML.load_file("#{RAILS_ROOT}/config/aws.yml")[RAILS_ENV],
                        :bucket => "flavorpulse-" + RAILS_ENV,
                        :path => ":class/:id/:style.:extension"
      validates_attachment_presence :file
      validates_attachment_size :file, :less_than => 5.megabytes
    
      before_save :delete_assets_in_same_theme_with_same_name
      after_create :copy_from_cloned_asset
    
      private
      def delete_assets_in_same_theme_with_same_name
        Asset.destroy_all({:theme_id => self.theme_id, :file_file_name => self.file_file_name})
      end
    
      def copy_from_cloned_asset
        if (!old_id.blank?)
          if (old_id > 0)
            old_asset = Asset.find(old_id)
            if (!old_asset.blank?)
              self.file = do_download_remote_image(old_asset.file.url)
              self.file.save
            end
          end
        end
      end
    
      def do_download_remote_image (image_url)
        io = open(URI.parse(image_url))
        def io.original_filename; base_uri.path.split('/').last; end
        io.original_filename.blank? ? nil : io
      rescue # catch url errors with validations instead of exceptions (Errno::ENOENT, OpenURI::HTTPError, etc...)
      end
    end
    

    有什么关于如何用回形针推文件的想法吗?我也不会反对使用亚马逊的AWS-S3 gem来实现这一点,但我似乎也不能让它发挥作用。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Community Jaime Torres    7 年前

    根据 this former question/answer ,应该可以使用以下简单的代码行:

    self.file = old_asset.file