【问题标题】:What is the best way to store blobs in rails 5?在 Rails 5 中存储 blob 的最佳方法是什么?
【发布时间】:2019-04-14 13:57:10
【问题描述】:

我正在创建一个录音机应用程序(rails 5)。我目前的应用程序能够开始录制、停止录制并将录制 (.wav) 保存到公共目录。我正在生成一个 blob,但目前没有对它做任何事情,因为我真的不“知道如何处理它”。

此应用程序的目的是能够录制您自己的音频并将其保存到应用程序内的用户配置文件中,然后稍后对数据执行其他各种操作。我以前使用carrierwave和回形针来管理多部分数据,但我没有使用过音频文件,所以我不确定最佳实践。以下是我的一些想法:

  1. 在服务器本身上存储实际文件是不可扩展的,所以这是不可能的。
  2. 在数据库中存储 blob。这可能有效,但我不确定在从 blob 转换回音频以及丢失数据时是否会出现明显的低效率。
  3. 在 aws 上存储 blob。与 #2 的想法基本相同,但转换时会丢失数据且效率低下。
  4. 在 aws 上存储实际文件。假设这是可能的。如果允许长音频,桶的大小可能会相当大。

我真的倾向于在我的数据库中使用 blob (#2) 来排除使用 3rd 方 API,如果这样做是一个好习惯的话。如果这是一个不错的选择,我将如何将 blob 存储在数据库中?我看到bytea 是来自其他一些响应的数据类型,但是那里会存储什么?整个一团?

例子:

数据:音频/ WAV; BASE64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQRChYECGFOAZwH ///////// FUmpZpkq17GDD0JATYCGQ2hyb21lV0GGQ2hyb21lFlSua7 + uvdeBAXPFh16n8rxO9UKDgQKGhkFfT1BVU2Oik09wdXNIZWFkAQEAAIC7AAAAAADhjbWERzuAAJ + BAWJkgSAfQ7Z1Af ///////// ngQCjQYiBAACA + 4MC0f / + 3 / abXFmCecYAQzBpCOhi / o3VWPm9t4OomPezg0lN7vXJNZDU1 / lsNMC5P / PIA + 0cQh0Ye5IyXuGV4 / IEeblfjEYYqTOlvApzLcAMqI8H1sRhHEHGp8p5KtsBLleXV0qODc7OtgErifrP6CuTzF6qP2AH4i9MlGQwtzxKNLBIHlgOpQgkzw4pByZXK4thmdAXUvRQtAtxYoJcC2 / iTY7af0IKBY0siodKsV + VFqAsOndoZJeTI1aG72UB / fo4cZnrUdwmKDROP + J661jhULtSnIKKWsy4jGTE .....

如果这不是最佳选择,您能否告诉我最佳选择以及如何实现?

编辑:抱歉,剧透并没有像我预期的那样发挥作用。

编辑 2:其他一些问题。

我不确定在https://edgeguides.rubyonrails.org/active_storage_overview.html 之后提供attach 方法实际上需要什么。现在我将音频作为文件传递给我的控制器:

#<ActionDispatch::Http::UploadedFile:0x007ff58958a788 @tempfile=#<Tempfile:/var/folders/xb/zm03wqls70gf3thlfy0d67bh0000gn/T/RackMultipart20190414-15311-1essuud.wav>, @original_filename="1555288144507.wav", @content_type="audio/wav", @headers="Content-Disposition: form-data; name=\"audio\"; filename=\"1555288144507.wav\"\r\nContent-Type: audio/wav\r\n">

我已经尝试了很多不同的变体,但是我的存储目录中保存的文件看起来很疯狂。

current_user.audio_recordings.attach(
  io: audio, 
  filename: 'file.wav', 
  content_type: 'audio/wav'
)

似乎我在 JS 中做的繁重工作可能比我需要的要多得多。

JS保存功能:

function saveRecording() {
    var data = new FormData();

    data.append("audio", recordingBlob, (new Date()).getTime() + ".wav");

    var request = new XMLHttpRequest();
    request.open("POST", "/landing_pages/save_audio");
    request.send(data);
    request.onload = function(oEvent) {
      if (request.status == 200) {
        console.log("Uploaded");
      } else {
        console.log("Error: " + request.status);
      }
    };
  }

【问题讨论】:

  • 你在使用 PostgreSQL 吗?

标签: javascript ruby-on-rails ruby ruby-on-rails-5


【解决方案1】:

如果您使用的是 PostgreSQL,我建议您不要将其保存为 bytea 和 BLOB,您可以在此处了解其好处。

https://wiki.postgresql.org/wiki/BinaryFilesInDB#bytea

https://github.com/diogob/carrierwave-postgresql

如果您选择将其保存在云提供商中,Rails 5 引入了 ActiveStorage,它是一个易于使用的框架,用于在多个后端进行文件存储。

https://edgeguides.rubyonrails.org/active_storage_overview.html

【讨论】:

  • 非常感谢。我认为 ActiveStorage 听起来是 PoC 的不错选择,甚至可能是全面的。
  • 无论如何你可以看看我的新编辑吗?我没有遵循我应该传递给 ActiveStorage 的附加方法的内容。我正在保存文件,但它们看起来像二进制文件并且没有扩展名。
  • 你能进一步解释你的新问题吗?
  • 当使用 ActiveStorage 的附加方法current_user.audio_recordings.attach() 时,它会在我的存储目录中创建一个文件,但它不是我所期望的.wav,它是一个二进制文件。我不确定我需要将什么传递给attach 方法的io 部分,或者我是否做错了。
  • 我完全错了,它只是在存储时剥离扩展名,一切都很好。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 2012-04-06
  • 2013-02-15
  • 2013-05-23
  • 2011-02-27
  • 2020-11-30
  • 2016-12-22
相关资源
最近更新 更多