【问题标题】:What is involved with changing attachment_fu's storage scheme?更改附件 fu 的存储方案涉及什么?
【发布时间】:2010-11-20 07:19:33
【问题描述】:

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

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

我希望将现有文件移至 S3,因此所有文件都在同一个位置,但如有必要,只要新文件移至 S3,旧文件就可以保留在原处。

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

【问题讨论】:

    标签: ruby-on-rails amazon-s3 attachment-fu


    【解决方案1】:

    没错。 id 使用 :file_system 存储填充。 除了重命名所有文件,您还可以更改 s3 后端模块以使用填充数字。

    file_system_backend.rb复制partitioned_path方法,放到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
    

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

    【讨论】:

      【解决方案2】:

      除了nilbus的回答,我还得修改s3_backend.rbbase_path方法返回一个空字符串,否则会插入attachment_path_id两次:

      def base_path
        return ''
      end
      

      【讨论】:

        【解决方案3】:

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

        def base_path
          attachment_options[:path_prefix]
        end
        

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

        def attachment_path_id
          ((respond_to?(:parent_id) && parent_id) || id) || 0
        end
        

        【讨论】:

          【解决方案4】:

          感谢所有帮助很大的回复。它也对我有用,但我必须这样做才能使 :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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-02-28
            • 1970-01-01
            • 1970-01-01
            • 2021-12-05
            • 1970-01-01
            • 2016-08-10
            • 2012-08-15
            相关资源
            最近更新 更多