Rails Active Storage设置文件夹以存储文件

时间:2018-06-17 03:34:19

标签: ruby-on-rails rails-activestorage

我使用Active Storage在Rails 5.2项目中存储文件。我已将文件保存到S3,但它们使用随机字符串文件名保存并直接保存到存储桶的根目录。我不介意随机文件名(我实际上更喜欢它用于我的用例),但是希望将不同的附件组织到文件夹中。

我的模型使用using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerControl : MonoBehaviour { public float speed; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void FixedUpdate () { float moveHorizontal = Input.GetAxis("Horizontal"); float moveVertical = Input.GetAxis("Vertical"); Vector3 movement = new Vector3(moveHorizontal,0.0f,moveVertical); Rigidbody.AddForce(movement*speed*Time.deltaTime); } 。我想指定将所有这些文件存储在S3中的has_one_attached :file文件夹中。我无法找到有关如何设置这些路径的任何文档。

/downloads之类的东西如果可能的话会很棒......

5 个答案:

答案 0 :(得分:2)

没有正式的方法来更改由ActiveStorage::Blob#key确定的路径,并且源代码为:

def key
  self[:key] ||= self.class.generate_unique_secure_token
end

ActieStorage::Blog.generate_unique_secure_token

def generate_unique_secure_token
  SecureRandom.base36(28)
end

因此,一种解决方法是重写key方法,如下所示:

# config/initializers/active_storage.rb
ActiveSupport.on_load(:active_storage_blob) do
  def key
    self[:key] ||= "my_folder/#{self.class.generate_unique_secure_token}"
  end
end

不用担心,这不会影响现有文件。但是您必须小心ActiveStorage是非常新的东西,它的源代码是变体。升级Rails版本时,请提醒自己看看该补丁是否引起了某些问题。

您可以从此处阅读ActiveStorage源代码:https://github.com/rails/rails/tree/master/activestorage

答案 1 :(得分:1)

截至目前ActiveStorage不支持此类功能。请参阅此linkhas_one_attached只接受namedependent

同样在GitHub的一个问题中,维护者明确提到他们显然不知道实现this之类的东西。

我可以想象的解决方法是,从前端上传文件,然后在key

中编写更新active_storage_blob_statement字段的服务

答案 2 :(得分:1)

使用 Cloudinary 服务的解决方案

如果您使用 Cloudinary,您可以在 storage.yml 上设置文件夹:

cloudinary:
  service: Cloudinary
  folder: <%= Rails.env %>

这样,Cloudinary 将根据您的 Rails 环境自动创建文件夹:

image

这是一个带有 Active Storage 的 long due issue,Cloudinary 团队似乎已经解决了这个问题。感谢您的出色工作❤️

答案 3 :(得分:0)

# config/initializers/active_storage.rb
ActiveSupport.on_load(:active_storage_blob) do
  def key
    sql_find_order_id = "select * from active_storage_attachments where blob_id = #{self.id}"
    active_storage_attachment = ActiveRecord::Base.connection.select_one(sql_find_order_id)

    # this variable record_id contains the id of object association in has_one_attached
    record_id = active_storage_attachment['record_id']

    self[:key] = "my_folder/#{self.class.generate_unique_secure_token}"
    self.save

    self[:key]
  end
end

答案 4 :(得分:0)

默认情况下,Active Storage 不包含路径/文件夹功能,但您可以通过

覆盖该功能

model.file.attach(key: "downloads/filename", io: File.open(file), content_type: file.content_type, filename: "#{file.original_filename}")

这样做会将带有您要存储文件的路径的密钥存储在 s3 子目录中,并将其上传到您想要的确切位置。