我正在開發一個遺留的 Rails 應用程式,最近升級到 Rails 5.2。它已經有一個帶有上傳功能的自己動手的影像實作,并且資料庫中已經有數百萬張影像。該Image模型belongs_to等模型; 它們中的每任一has_many :images或has_one :image。
這是 Image 表的架構:
create_table "images", id: :integer, unsigned: true, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.string "content_type", limit: 100
t.integer "user_id"
t.date "when"
t.text "notes"
t.string "copyright_holder", limit: 100
t.integer "license_id", default: 1, null: false
t.integer "num_views", default: 0, null: false
t.datetime "last_view"
t.integer "width"
t.integer "height"
t.float "vote_cache"
t.boolean "ok_for_export", default: true, null: false
t.string "original_name", limit: 120, default: ""
t.boolean "transferred", default: false, null: false
t.boolean "gps_stripped", default: false, null: false
end
執行作業的一部分是,有一個子類Image,Image::Url即獲得影像的URL(在AWS)的基礎上,尺寸要求已經被ImageMagick的產生的各種尺寸的。
class Image
class Url
SUBDIRECTORIES = {
full_size: "orig",
huge: "1280",
large: "960",
medium: "640",
small: "320",
thumbnail: "thumb"
}.freeze
SUBDIRECTORY_TO_SIZE = {
"orig" => :full_size,
"1280" => :huge,
"960" => :large,
"640" => :medium,
"320" => :small,
"thumb" => :thumbnail
}.freeze
attr_accessor :size, :id, :transferred, :extension
def initialize(args)
size = args[:size]
size = SUBDIRECTORY_TO_SIZE[size] unless size.is_a?(Symbol)
size = :full_size if size == :original
self.size = size
self.id = args[:id]
self.transferred = args[:transferred]
self.extension = args[:extension]
end
def url
for source in source_order
return source_url(source) if source_exists?(source)
end
source_url(fallback_source)
end
def source_exists?(source)
spec = format_spec(source, :test)
case spec
when :transferred_flag
transferred
when /^file:/
local_file_exists?(spec)
when /^http:/
remote_file_exists?(spec)
when /^https:/
remote_file_exists?(spec)
else
raise("Invalid image source test spec for "\
"#{source.inspect}: #{spec.inspect}")
end
end
def local_file_exists?(spec)
File.exist?(file_name(spec)[7..])
end
def remote_file_exists?(spec)
url = URI.parse(file_name(spec))
result = Net::HTTP.new(url.host, url.port).request_head(url.path)
result.code == 200
end
def source_url(source)
file_name(format_spec(source, :read))
end
def file_name(path)
"#{path}/#{subdirectory}/#{id}.#{extension}"
end
def subdirectory
SUBDIRECTORIES[size] || raise("Invalid size: #{size.inspect}")
end
def source_order
OurApp.image_precedence[size] || OurApp.image_precedence[:default]
end
def fallback_source
OurApp.image_fallback_source
end
def format_spec(source, mode)
spec = specs(source)[mode]
spec.is_a?(String) ? format(spec, root: OurApp.root) : spec
end
def specs(source)
OurApp.image_sources[source] ||
raise("Missing image source: #{source.inspect}")
end
end
end
所以我在考慮我們現有的資料表是否可以以某種方式遷移到 Active Storage(它沒有安裝在這個 Rails 應用程式上)。
EDIT One question suggested by the above class, which I did not write, is whether our established image URL structure would be compatible with Active Storage. Would this "url generator" work even if the actual source url info is migrated to the blobs? It's possible i'm not understanding how AWS storage works, maybe there is no real "source" url.
All the tutorials and explainers I've found discuss installing Active Storage on a new Rails app, or using it to add attachments to existing models. That's not my situation -- I already have an Image model relating to a dozen other models, and they already know what their "attachments" i.e. Image relations, are.
我的問題是,Active Storage 能否以某種方式利用現有的 Image 表及其關系 - 或者 Active Storage 是否可以更恰當地理解為無法與其集成的這種自行設定的替代方案。
有一個關于“Rails Active Storage without model”的問題,似乎暗示可能會發生 Active Storage 和模型之間的映射。我不明白的是 Active Storage 和現有影像模型之間的關系。據我了解,影像模型將has_one_attached或has_many_attached(作為用戶或產品將具有附件)是沒有意義的- 它已經是附件本身的模型。還是我弄錯了?
uj5u.com熱心網友回復:
ActiveStorage 的核心實際上是三個表(和模型),它們與您的影像表有些對應:
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
# Use Active Record's configured type for primary and foreign keys
primary_key_type, foreign_key_type = primary_and_foreign_key_types
create_table :active_storage_blobs, id: primary_key_type do |t|
t.string :key, null: false
t.string :filename, null: false
t.string :content_type
t.text :metadata
t.string :service_name, null: false
t.bigint :byte_size, null: false
t.string :checksum, null: false
if connection.supports_datetime_with_precision?
t.datetime :created_at, precision: 6, null: false
else
t.datetime :created_at, null: false
end
t.index [ :key ], unique: true
end
create_table :active_storage_attachments, id: primary_key_type do |t|
t.string :name, null: false
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
t.references :blob, null: false, type: foreign_key_type
if connection.supports_datetime_with_precision?
t.datetime :created_at, precision: 6, null: false
else
t.datetime :created_at, null: false
end
t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
create_table :active_storage_variant_records, id: primary_key_type do |t|
t.belongs_to :blob, null: false, index: false, type: foreign_key_type
t.string :variation_digest, null: false
t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
private
def primary_and_foreign_key_types
config = Rails.configuration.generators
setting = config.options[config.orm][:primary_key_type]
primary_key_type = setting || :primary_key
foreign_key_type = setting || :bigint
[primary_key_type, foreign_key_type]
end
end
從遷移中可以看出,它使用active_storage_blobs來存盤有關所存盤檔案的實際資訊。一個 blob 也可以有多個變體。
active_storage_attachments通過多型關聯將 blob 與資源(附加附件的模型)連接起來。這使您可以添加has_one_attached/has_many_attached到應用程式中的任何模型,而無需添加任何額外的資料庫列或表。
所以我在考慮 Active Storage(它沒有安裝在這個 Rails 應用程式上)是否可以與這個現有的設定一起作業。
讓我們這樣說 - 您不應該期望您可以將舊資料插入到 ActiveStorage 中并播放。它是一個非常固執的軟體,主要圍繞能夠以最少的配置插入任意數量的模型的目標而設計。
ActiveStorage 可能可以與您現有的設定協同作業(為新記錄替換它),但用 AS 替換舊代碼很可能需要進行大量資料遷移,您還需要很好地了解 AS 的作業原理。
我不明白的是 Active Storage 和現有影像模型之間的關系。
那是因為真的沒有。ActiveSupport::Attachment并ActiveSupport::Blob為 Rails 應用程式中具有附件的所有模型提供相同的角色。它的設計沒有考慮到遺留支持。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/338834.html
上一篇:Rails-過濾多對多
