📤
CarrierWave 用のカラムが NOT NULL のときのローカルデータの作り方
ラブグラフでエンジニアをしております横江( @yokoe24 )です!
画像のアップロードに CarrierWave を使っているのですが、
この前ちょっとだけ困ったことがあったので解決方法を記します。
データベースのファイル用カラムが NOT NULL のテーブル
例えばこのようなテーブルがあるとしましょう。
create_table :user_settings,charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t|
t.bigint :user_id, null: false
t.string :avatar, null: false # アバター画像
t.datetime :created_at, null: false, precision: 6
t.datetime :updated_at, null: false, precision: 6
t.index :user_id, unique: true
end
add_foreign_key :user_settings, :users, on_update: :cascade
モデルはこのようになっています。
class UserSetting < ApplicationRecord
mount_uploader :avatar, AvatarUploader
belongs_to :user
validates :avatar, presence: true
end
現実では、ユーザー作成時にアバター画像が必ず設定されていないという
作りになっていることはほぼありえないのですが、今回はそういう実装になっていたとしてください。
このとき、ダミーデータとしてユーザーを作りたい場合は大変です。
user = User.first
UserSetting.create!(user: user, avatar: "")
=> バリデーションに失敗しました: avatarを入力してください (ActiveRecord::RecordInvalid)
ってな感じでバリデーションエラーになってしまいます。
avatar カラムの値はどのように設定すればいいのでしょうか・・・?
解決方法
いったい avatar カラムにどんな String(文字列)を入れればいいのか……と最初は悩んだのですが、
解決方法は実はとてもカンタンで、
File.open
メソッドを使って File
オブジェクト を作成すればOKです!
ローカルのファイルを File.open で開いて、avatar カラムに代入しましょう。
file = File.open("app/assets/images/dummy_avatar.png")
user = User.first
UserSetting.create!(user: user, avatar: file)
なにか適当な画像ファイルを
app/assets/images
に dummy_avatar.png
という名前で置いて、
それを読み込むようにしています。
全部同じ画像になってしまいますが、以下のように一度に大量の UserSetting を作ることも可能です。
file = File.open("app/assets/images/dummy_avatar.png")
User.first(100).pluck(:id).each do |user_id|
UserSetting.create!(user_id: user_id, avatar: file)
end
このようにして、CarrierWave のためのカラムがあっても
初期値をカンタンに設定できることがわかりました!
Discussion