2

我有一个使用 attachment_fu 的 rails 应用程序。目前,它:file_system用于存储,但我想将其更改为:s3,以便在上传更多文件时更好地缩放。

这与什么有关?我想如果我只是将代码切换为 use :s3,所有旧链接都会被破坏。我需要将现有文件从文件系统复制到 S3 吗?谷歌搜索并没有出现太多关于该主题的信息。

我更愿意将现有文件移动到 S3,所以一切都在同一个地方,但如果有必要,旧文件可以留在原处,只要新文件转到 S3。

编辑: 所以,它不像将文件复制到 S3 那样简单;URL 是使用不同的方案创建的。当它们存储在 中:file_system时,文件最终会出现在 /public/photos/0000/0001/file.name 等位置,但相同的文件:s3可能会出现在 0/1/file.name 中。我认为它正在使用 id 东西,只是用零填充(或不填充),但我不确定。

4

4 回答 4

4

这是正确的。id 使用 :file_system 存储填充。您可以更改 s3 后端模块以使用填充数字,而不是重命名所有文件。

复制partitioned_path方法file_system_backend.rb并将其放入s3_backend.rb.

    def partitioned_path(*args)
      if respond_to?(:attachment_options) && attachment_options[:partition] == false
        args
      elsif attachment_options[:uuid_primary_key]
        # Primary key is a 128-bit UUID in hex format. Split it into 2 components.
        path_id = attachment_path_id.to_s
        component1 = path_id[0..15] || "-"
        component2 = path_id[16..-1] || "-"
        [component1, component2] + args
      else
        path_id = attachment_path_id
        if path_id.is_a?(Integer)
          # Primary key is an integer. Split it after padding it with 0.
          ("%08d" % path_id).scan(/..../) + args
        else
          # Primary key is a String. Hash it, then split it into 4 components.
          hash = Digest::SHA512.hexdigest(path_id.to_s)
          [hash[0..31], hash[32..63], hash[64..95], hash[96..127]] + args
        end
      end
    end

修改s3_backend.rbfull_filename方法以使用partitioned_path.

    def full_filename(thumbnail = nil)
      File.join(base_path, *partitioned_path(thumbnail_name_for(thumbnail)))
    end

attach_fu 现在将创建与 file_system 后端名称相同的路径,因此您只需将文件复制到 s3 而无需重命名所有内容。

于 2009-11-03T19:24:59.580 回答
2

除了 nilbus 的回答,我不得不修改s3_backend.rb'base_path方法以返回一个空字符串,否则它会插入attachment_path_id两次:

def base_path
  return ''
end
于 2011-01-21T14:35:47.423 回答
2

除了 nilbus 的回答之外,对我有用的是修改 s3_backend.rb 的base_path方法以仍然使用 path_prefix (默认情况下是表名):

def base_path
  attachment_options[:path_prefix]
end

而且,我不得不attachment_path_id从 file_system_backend.rb 中取出并替换 s3_backend.rb 中的那个,否则partitioned_path我总是认为我的主键是一个字符串:

def attachment_path_id
  ((respond_to?(:parent_id) && parent_id) || id) || 0
end
于 2011-05-12T21:09:02.123 回答
0

感谢所有那些帮助很大的回复。它也对我有用,但我必须这样做才能使:thumbnail_class选项起作用:

def full_filename(thumbnail = nil)
  prefix = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s
  File.join(prefix, *partitioned_path(thumbnail_name_for(thumbnail)))
end
于 2013-02-19T16:15:01.600 回答