在Postgresql上使用UUID的Rails 5.2 ActiveStorage [英] Rails 5.2 ActiveStorage with UUIDs on Postgresql

查看:93
本文介绍了在Postgresql上使用UUID的Rails 5.2 ActiveStorage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Postgresql数据库上,我们使用uuids作为主键的应用程序。 (标准设置在此处中进行了描述)。

We have our app using uuids are primary keys, on a Postgresql Database. (Standard setup described here).

我们按照此处所述的过程集成了ActiveStorage一个>。使用 rails active_storage:install 的标准设置,并使用 rails db:migrate 进行迁移。

We integrated ActiveStorage following the process described here. A standard setup using rails active_storage:install and migrated using rails db:migrate.

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

We have a model & corresponding controller as follows:

# 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

我们观察到前几组图像已与模型实例正确关联,但是随后我们习惯于为模型实例获取随机图像,或者根本没有图像。每次重新启动服务器时,我们都会得到正确的前几张图像,但是随后这是不可预测的。

We observed that the first few sets of image were correctly associated with the model instances, but then we used to get random images for model instance, or got no image at all. Every time, we restart the server, we get first few images right, but then it was unpredictable.

不确定,出了什么问题,我们在Rails控制台中进行了调试:

Unsure, of what's going wrong, we debugged in rails console:

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">

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

On saving the instance and retrieving file name we got a random file, we uploaded previously.

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

@message.save

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

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

Looking for an explanation for this weird behaviour, and a possible solution too.

推荐答案

在活动存储区中逐行运行源代码,并运行相同的命令

After hours of going line by line in the activestorage source code, and running the same commands

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

再次。我们一次又一次得到相同的随机结果。然后,我们在将图像附加到消息上的同时浏览了打印的日志栏,并观察到以下内容:

again and again. We got same random results again and again. Then we went through the logs rails printed while attaching the image to message and observed the following:

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。这是我们出问题的地方。

record_id was being set as 534736, instead of an uuid. Here's where we went wrong.

活动存储期望我们的Message模型使用整数外键,而我们希望它改用uuid。因此,我们必须解决迁移问题,使用uuid代替整数外键。

Active storage was expecting integer foreign key to our Message model, and we wanted it to use uuids instead. So we had to fix our migration, to use uuids instead of integer foreign keys.

解决方案:

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

希望这对遇到类似问题的人有所帮助。欢呼!

Hope this helps, someone facing similar issues. cheers!

这篇关于在Postgresql上使用UUID的Rails 5.2 ActiveStorage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆