围绕同一问题的多个问题,主动存储返回文件URL的方式
现在使用默认设置,以下(云或本地)以某种方式返回以下内容:
_domain/_path/_superlong_hash/_original_filename._ext
给定回形针或许多其他现有的宝石,_path/_superlong_hash/_original_filename._ext部分可以自定义,最终可以在任何文件的干净URL中
意思是:
_path用更自定义的东西"代理" ?_superlong_hash?为了使它成为一个单行,如何定制文件URL?
我在这里和那里看到人们最终创建自定义控制器以提供具有体面网址的文件,但让我们承认这是不行(恕我直言)
我正在使用Ruby on Rails构建网站。要上传图像,我正在使用Active Storage和Amazon S3。一切都很好。用户可以上传图像,并且可以在网站上查看图像(图像是公开的)。
现在,在生产中,图像的URL为:https : //example.com/rails/active_storage/representations/1ej21h ...
哪个将302返回到S3存储桶:https : //my-bucket.amazonaws.com/variants/9jdh2 ...
我不喜欢:
我想使用Cloudfront来提供这些图像。
我在Google和StackOverflow上的《 Rails指南》中进行了搜索,但到目前为止找不到合适的答案。
目前是否有将Cloudfront与Active Storage结合使用的解决方案?
编辑:更多上下文:每张图片至少每分钟将在正常流量和来自不同国家的情况下加载1000次。我不想让服务器承受这种压力(它还有其他要求要处理)。我希望用户尽快加载这些图像。因此,Cloudfront作为这些图像(公共图像,无需获取签名的URL)的CDN。
ruby-on-rails amazon-s3 amazon-cloudfront ruby-on-rails-5 rails-activestorage
给定具有ActiveStorage的模型
class User
has_one_attached :avatar
end
Run Code Online (Sandbox Code Playgroud)
我可以检查一个用户是否有化身
@user.avatar.attached?
Run Code Online (Sandbox Code Playgroud)
但是,如何返回具有附件(或没有附件)的所有用户的集合?
我尝试使用joins返回带有附件的所有Users,但这在blob或附件表上似乎都不起作用,或者我的语法不正确。
我确定我忽略了一些显而易见的事情。是否可以按照以下方式做一些事情:
User.where(attached_avatar: nil)
Run Code Online (Sandbox Code Playgroud)
如果是这样,在哪里记录?
使用 ActiveStorage 时,如何为附加文件创建范围。
例如:
class Check < ActiveRecord::Base
has_one_attached :image
end
Run Code Online (Sandbox Code Playgroud)
我想要Check.has_attached_image只返回存在附加图像的记录。
我知道这ActiveStorage提供了一个with_attached_image范围。但这似乎不起作用:
irb(main):009:0> Check.with_attached_image.to_sql
=> "SELECT \"checks\".* FROM \"checks\""
我尝试将 Active Storage 与 Amazon Web Services 一起使用,而不是 Carrierwave 和 Cloudinary。
使用 Carrierwave,我有一些功能可以在通过 UploaderController 上传之前调整图像大小。
但是如何使用 Active Storage 做到这一点?
我试试这个:
宝石文件:
gem 'aws-sdk-s3', require: false
gem 'image_processing', '~> 1.2'
gem 'mini_magick', '~>4.9'
Run Code Online (Sandbox Code Playgroud)
项目.rb
class Item < ApplicationRecord
has_one_attached :photo
end
Run Code Online (Sandbox Code Playgroud)
我认为有一个表格:
<%= f.input :photo, input_html: { accept: ('image') } %>
Run Code Online (Sandbox Code Playgroud)
我把这个对象作为照片:
#<ActiveStorage::Attached::One:0x00005641d296e1b8 @name="photo", @record=#<Item id: nil, name: "test0941", verbe: "To Lend", collection_id: nil, created_at: nil, updated_at: nil, price_cents: 0, description: "", category_id: 78, photo: nil>, @dependent=:purge_later>
Run Code Online (Sandbox Code Playgroud)
在我的控制器中:
@item = Item.new(item_params) …Run Code Online (Sandbox Code Playgroud) 我在 Rails 5.2 中使用主动存储。我遵循 EdgeRails 指南,并已将 Active-Storage 配置为使用本地磁盘。
当我使用 Rails 应用程序时,文件上传效果很好。
但是,问题是我需要在不使用 Rails 作为中介的情况下物理访问这些上传的文件。
对文件存储位置的查询返回:
url_for(@employee_staff.avatar)
=> "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBGUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--e76664d247cb5437fe1cd11f7ee0ded24f95aee2/profilepic3.jpeg"
Run Code Online (Sandbox Code Playgroud)
我想弄清楚这个文件路径在我的本地磁盘中的保存位置。到目前为止,我没有运气。
非常感谢有关 Active-Storage 如何工作以及我可以在哪里看到上传文件的任何解释。
我在我的模型中创建了一个方法来验证上传文件类型。但它不起作用,我认为这是因为我使用的是直接上传。
是否可以通过使用活动存储直接上传来验证文件类型?我该怎么办?
我试过:
模型:
validate :correct_video_type
def correct_video_type
if video.attached? && video.content_type.in?(%w(video/mov video/mp4 video/avi video/mpeg))
errors.add(:video, "Must be video format")
elsif video.attached? == false
errors.add(:video, "Video must be attached")
end
end
Run Code Online (Sandbox Code Playgroud)
看法:
<%= form.file_field :video, class: "upload", direct_upload: true %>
Run Code Online (Sandbox Code Playgroud)
什么都没有得到验证......
我也尝试过前端验证,但这不起作用:
<%= form.file_field :video, class: "upload", direct_upload: true, accept: 'video/mov, video/mpeg, video/mp4, video/avi' %>
Run Code Online (Sandbox Code Playgroud)
这些都没有奏效。即使前端工作,我仍然想在后端进一步验证它。
我怎样才能验证这一点?
如果您使用 ActiveStorage 并且您有一个包含 N 个图像的页面,您会收到 N 个对 Rails 应用程序的额外请求(即 N 个重定向)。如果页面上有数十张图像,这意味着浪费大量服务器资源。
我知道重定向对签名 URL 很有用。但是我想知道为什么 Rails 不预先计算最终的签名 URL 并将其嵌入到 HTML 页面中......这样我们可以保持签名 URL/受保护文件的优势,而无需对 Rails 服务器进行 N 次额外调用。
是否可以直接在 HTML 中包含图像变体的最终 URL/预签名 URL(从而避免重定向)?否则,为什么不可能?
我们有办法禁用操作文本的附件吗?类似于下面的 has_rich_text :content,attachment: false
这样,我们就可以从数据库中删除 active_storage_blobs、active_storage_attachments 表。在这种情况下,只有 action_text_rich_texts 表才能满足目的。
rich-text-editor rails-activestorage ruby-on-rails-6 actiontext
我在带有 AWS 的 Rails 站点上使用 Active Storage。升级到 6.1 后,我想根据指南配置公共访问,以便我的图像具有永久 URL。
我已经确定我需要保持现有服务原样,以便之前上传的图像继续工作。我创建了一个新的服务和配置的应用程序使用它这样。
以前的图像继续这样工作,但新图像上传会导致 Aws::S3::Errors::AccessDenied。请注意,使用的凭据与之前的工作非公共服务中的凭据完全相同。该指南提到存储桶需要具有适当的权限,但没有确切地需要设置什么。
在 AWS 中,“阻止公共访问(存储桶设置)”部分全部设置为“关闭”。在“访问控制列表 (ACL)”中,“存储桶所有者(您的 AWS 账户)”对“对象”和“存储桶 ACL”都有“列出、写入”。没有列出其他权限。我尝试将“所有人(公共访问)”更改为“对象”的“列表”和“存储桶 ACL”的“读取” - 似乎没有解决问题。
如何使用 Active Storage 获取公共 URL?