如何设置回形针的存储机制基础上,目前的Rails环境?回形针、基础上、如何设置、机制

2023-09-11 08:15:29 作者:情话烫嘴

我有一个具有多个模型与全部上传到S3回形针附件的Rails应用程序。这个应用程序还具有运行往往一个大的测试套件。这样做的缺点是,一吨的文件都上传到每一个试运行我们的S3帐户,使得测试套件运行缓慢。它也减慢发展一点,需要你有为了工作在code互联网连接。

I have a rails application that has multiple models with paperclip attachments that are all uploaded to S3. This app also has a large test suite that is run quite often. The downside with this is that a ton of files are uploaded to our S3 account on every test run, making the test suite run slowly. It also slows down development a bit, and requires you to have an internet connection in order to work on the code.

有没有一种合理的方式来设置基于Rails环境回形针存储机制?理想的情况下,我们的测试和开发环境将使用本地文件系统存储和生产环境将使用S3存储

Is there a reasonable way to set the paperclip storage mechanism based on the Rails environment? Ideally, our test and development environments would use the local filesystem storage, and the production environment would use S3 storage.

我也想提取这个逻辑到某种共享的模块,因为我们有几个模式,将需要此行为。我想,以避免像这里面的每个模型的解决方案:

I'd also like to extract this logic into a shared module of some kind, since we have several models that will need this behavior. I'd like to avoid a solution like this inside of every model:

### We don't want to do this in our models...
if Rails.env.production?
  has_attached_file :image, :styles => {...},
                    :path => "images/:uuid_partition/:uuid/:style.:extension",
                    :storage => :s3,
                    :url => ':s3_authenticated_url', # generates an expiring url
                    :s3_credentials => File.join(Rails.root, 'config', 's3.yml'),
                    :s3_permissions => 'private',
                    :s3_protocol => 'https'
else
  has_attached_file :image, :styles => {...},
                    :storage => :filesystem
                    # Default :path and :url should be used for dev/test envs.
end

更新:的粘性部分是附件的:路径:网址选项​​需要取决于哪个存储系统被用于不同

Update: The sticky part is that the attachment's :path and :url options need to differ depending on which storage system is being used.

任何意见或建议,将不胜AP preciated! : - )

Any advice or suggestions would be greatly appreciated! :-)

推荐答案

与它玩了一段时间后,我想出了一个模块,我想要做什么。

After playing around with it for a while, I came up with a module that does what I want.

应用程序/模型/共享/ attachment_helper.rb

module Shared
  module AttachmentHelper

    def self.included(base)
      base.extend ClassMethods
    end

    module ClassMethods
      def has_attachment(name, options = {})

        # generates a string containing the singular model name and the pluralized attachment name.
        # Examples: "user_avatars" or "asset_uploads" or "message_previews"
        attachment_owner    = self.table_name.singularize
        attachment_folder   = "#{attachment_owner}_#{name.to_s.pluralize}"

        # we want to create a path for the upload that looks like:
        # message_previews/00/11/22/001122deadbeef/thumbnail.png
        attachment_path     = "#{attachment_folder}/:uuid_partition/:uuid/:style.:extension"

        if Rails.env.production?
          options[:path]            ||= attachment_path
          options[:storage]         ||= :s3
          options[:url]             ||= ':s3_authenticated_url'
          options[:s3_credentials]  ||= File.join(Rails.root, 'config', 's3.yml')
          options[:s3_permissions]  ||= 'private'
          options[:s3_protocol]     ||= 'https'
        else
          # For local Dev/Test envs, use the default filesystem, but separate the environments
          # into different folders, so you can delete test files without breaking dev files.
          options[:path]  ||= ":rails_root/public/system/attachments/#{Rails.env}/#{attachment_path}"
          options[:url]   ||= "/system/attachments/#{Rails.env}/#{attachment_path}"
        end

        # pass things off to paperclip.
        has_attached_file name, options
      end
    end
  end
end

(注:我在上面使用一些自定义的回形针插值,如:uuid_partition :UUID :s​​3_authenticated_url 你需要修改的东西根据需要为特定的应用程序)的

(Note: I'm using some custom paperclip interpolations above, like :uuid_partition, :uuid and :s3_authenticated_url. You'll need to modify things as needed for your particular application)

现在,对于具有回形针附件的每一个模型,你就必须包括该共享的模块,并调用 has_​​attachment 方法(而不是回形针的 has_attached_file

Now, for every model that has paperclip attachments, you just have to include this shared module, and call the has_attachment method (instead of paperclip's has_attached_file)

这是例子模型文件:应用程序/模型/ user.rb

class User < ActiveRecord::Base
  include Shared::AttachmentHelper  
  has_attachment :avatar, :styles => { :thumbnail => "100x100>" }
end

有了这个地方,你必须保存在以下位置的文件,根据您的环境:

With this in place, you'll have files saved to the following locations, depending on your environment:

发展:

RAILS_ROOT +公共/附件/开发/ user_avatars / AA / BB / CC / AABBCCDDEEFF / thumbnail.jpg

测试:

RAILS_ROOT +公共/附件/测试/ user_avatars / AA / BB / CC / AABBCCDDEEFF / thumbnail.jpg

制作:

https://s3.amazonaws.com/your-bucket-name/user_avatars/aa/bb/cc/aabbccddeeff/thumbnail.jpg

这确实我在寻找什么,希望它会证明是有用的给别人了。 :)

This does exactly what I'm looking for, hopefully it'll prove useful to someone else too. :)

约翰