暇人じゃない

Rails コンソールから Active Storage のファイルアップロードを実行する
Rails

Active Storage が用意した Web API を使用せず、Rails のコンソールやバッチなどでファイルをアップロードしたいことがあったので、方法をメモする。

Rails のバージョンは v6.1.4.1。

以下のモデルを例にする。

class Item < ApplicationRecord
  has_one_attached :image
end

手順としては「ファイルをアップロード」、「モデルオブジェクトに紐付ける」の 2 つになる。

ファイルをアップロード

ActiveStorage::Blob.create_and_upload! にファイルの IO オブジェクトを渡すと、設定したサービスにファイルがアップロードされて、ActiveStorage::Blob オブジェクトが返ってくる。

path = "/path/to/image.jpg"
blob = ActiveStorage::Blob.create_and_upload!(io: File.new(path),  filename: File.basename(path))
=> #<ActiveStorage::Blob:0x00007f8fbd8b8c48
 id: 24,
 key: "fgaz4a2ekzxllwh9m22r948u81wx",
 filename: "image.jpg",
 content_type: "image/jpeg",
 metadata: {"identified"=>true},
 byte_size: 28815,
 checksum: "iGjE+wTmWXNGMXpFVgoiRQ==",
 created_at: Sat, 25 Sep 2021 15:26:42.980577000 JST +09:00,
 service_name: "local">

モデルに紐付ける

ActiveStorage::Blob オブジェクトを、 Item モデルオブジェクトに生成されている image= メソッドに渡すと紐付けることができる。

Item.create!(image: blob)

他のやり方としては、image.attach メソッドに Signed ID を渡しても紐付けることが可能。

item = Item.new
item.image.attach(blob.signed_id)
item.save!

About

chocoby (GitHub / Twitter)

個人事業主のソフトウェア開発者です。 Ruby と Rails を使った Web サービスの開発を得意としています。

CurryBu というサービスや、jp_prefecture という Gem を作っています。