首页 文章

在Postgresql上使用UUID的Rails 5.2 ActiveStorage

提问于
浏览
2

我们的应用程序使用uuids是Postgresql数据库的主键 . (标准设置描述here) .

我们按照here描述的流程集成了ActiveStorage . 使用 rails active_storage:install 的标准设置,并使用 rails db:migrate 进行迁移 .

我们有一个模型和相应的控制器如下:

# Model
class Message < ApplicationRecord
  has_one_attached :image

  def filename
    image&.attachment&.blob&.filename
  end
end

# Controller
class MessagesController < ApplicationController
  def create
    message = Message.create!(message_params)
    redirect_to message
  end

  private
    def message_params
      params.require(:message).permit(:title, :content, :image)
    end
end

我们观察到前几组图像与模型实例正确关联,但之后我们习惯于为模型实例获取随机图像,或者根本没有图像 . 每次,我们重新启动服务器,我们先得到几张图片,但后来却无法预测 .

不确定,我们在rails控制台中调试了什么问题:

params[:image]
=> #<ActionDispatch::Http::UploadedFile:0x007fcf2fa97b70 @tempfile=#<Tempfile:/var/folders/dt/05ncjr6s52ggc4bk6fs521qw0000gn/T/RackMultipart20180726-8503-vg36kz.pdf>, @original_filename="sample.pdf", @content_type="application/pdf", @headers="Content-Disposition: form-data; name=\"file\"; filename=\"sample.pdf\"\r\nContent-Type: application/pdf\r\n">

在保存实例和检索文件名时,我们得到了一个随机文件,我们之前上传过 .

@message = Message.new(message_params)
@message.filename
=> #<ActiveStorage::Filename:0x007fcf32cfd9e8 @filename="sample.pdf">

@message.save

@message.filename
=> #<ActiveStorage::Filename:0x007f82f2ad4ef0 @filename="OtherSamplePdf.pdf">

寻找这种奇怪行为的解释,以及可能的解决方案 .

1 回答

  • 9

    在activestorage source code中逐行走了几个小时,然后运行相同的命令

    @message = Message.new(message_params)
    @message.save
    

    一次又一次 . 我们一次又一次得到相同的随机结果 . 然后,我们在将图像附加到消息时检查了打印的日志轨道并观察了以下内容:

    S3 Storage (363.4ms) Uploaded file to key: KBKeHJARTjnsVjkgSbbii4Bz (checksum: S0GjR1EyvYYbMKh44wqlag==)
    
    ActiveStorage::Blob Create (0.4ms)  INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["key", "KBKeHJARTjnsVjkgSbbii4Bz"], ["filename", "sample.pdf"], ["content_type", "application/pdf"], ["metadata", "{\"identified\":true}"], ["byte_size", 3028], ["checksum", "S0GjR1EyvYYbMKh44wqlag=="], ["created_at", "2018-07-26 04:54:33.029769"]]
    
    ActiveStorage::Attachment Create (2.7ms)  INSERT INTO "active_storage_attachments" ("name", "record_type", "record_id", "blob_id", "created_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["name", "file"], ["record_type", "Message"], ["record_id", "534736"], ["blob_id", "0"], ["created_at", "2018-07-26 05:04:35.958831"]]
    

    record_id 被设置为 534736 ,而不是uuid . 这是我们出错的地方 .

    期望Active存储器对我们的Message模型使用整数外键,我们希望它使用uuids代替 . 所以我们必须修复我们的迁移,使用uuids而不是整数外键 .

    解:

    class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
      def change
        create_table :active_storage_blobs, id: :uuid do |t|
          t.string   :key,        null: false
          t.string   :filename,   null: false
          t.string   :content_type
          t.text     :metadata
          t.bigint   :byte_size,  null: false
          t.string   :checksum,   null: false
          t.datetime :created_at, null: false
    
          t.index [ :key ], unique: true
        end
    
        create_table :active_storage_attachments, id: :uuid do |t|
          t.string     :name,     null: false
          t.references :record,   null: false, polymorphic: true, index: false, type: :uuid
          t.references :blob,     null: false, type: :uuid
    
          t.datetime :created_at, null: false
    
          t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
        end
      end
    end
    

    希望这有帮助,有人面临类似的问题 . 干杯!

相关问题