1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】seeds.rbでサンプルデータ作成時に画像も一緒に生成する(ActiveStorage使用)

Last updated at Posted at 2021-03-06

環境

macOS: Big Sur Ver11.2.2
Rails: 6.0.0
Ruby: 2.6.5

前提

Railsで開発中しており、deviseを使ってユーザー登録関係を実装済み(Userモデル)。
さらに、UserモデルはActiveStorageにより画像を1枚添付できるようになっている(必ず添付しなければならない制約をつけてます)。
モデルのコードはこんな感じで、 has_one_attached と :image属性にpresence: trueが指定されているのがわかります。

class User < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :prefecture
  belongs_to :category
  has_one_attached :image

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  # パスワードは半角英数混合で8文字
  validates :password, format: { with: /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]{8}\z/i }
  with_options presence: true do
    validates :shop_name
    validates :address
    validates :business_hours
    validates :holiday
    validates :image
    validates :phone_number, format: { with: /\A0[1-9]\d{0,3}[-(]\d{1,4}[-)]\d{4}\z/ }
    with_options numericality: { other_than: 0 } do
      validates :category_id
      validates :prefecture_id
    end
  end
end


やりたいこと

ユーザーに紐づく画像をトップページに表示させたかったので、サンプルデータを20~30件くらい作って一気に表示させてみようと思いました。
新規登録されたユーザーの画像がトップページにズラッと並ぶ感じです。

試したこと①

seeds.rbに以下のとおり記述。

20.times do |n|
  user = User.create!(
    shop_name: "お店#{ n + 1 }",
    email: "seed#{ n + 1 }@seed.com",
    password: "pass1234",
    password_confirmation: "pass1234",
    category_id: rand(1..10),
    prefecture_id: rand(1..47),
    address: "仮町仮番地123-1",
    business_hours: "9時〜17時",
    holiday: "月曜",
    phone_number: "090-1234-5678",
    image: open("./db/fixtures/seed.jpg")
end

結果、「ファイルが見つからない、、」というエラー。

試したこと②

20.times do |n|
  user = User.create!(
    shop_name: "お店#{ n + 1 }",
    email: "seed#{ n + 1 }@seed.com",
    password: "pass1234",
    password_confirmation: "pass1234",
    category_id: rand(1..10),
    prefecture_id: rand(1..47),
    address: "仮町仮番地123-1",
    business_hours: "9時〜17時",
    holiday: "月曜",
    phone_number: "090-1234-5678",
  )
  user.image.attach(io: File.open(Rails.root.join('app/assets/images/test.jpg')),
                  filename: 'test.jpg')
end

結果、「imageがバリデーションに引っかかりました!」という指摘を受けました。

試したこと③

20.times do |n|
  user = User.create!(
    shop_name: "お店#{ n + 1 }",
    email: "seed#{ n + 1 }@seed.com",
    password: "pass1234",
    password_confirmation: "pass1234",
    category_id: rand(1..10),
    prefecture_id: rand(1..47),
    address: "仮町仮番地123-1",
    business_hours: "9時〜17時",
    holiday: "月曜",
    phone_number: "090-1234-5678",
    user.image.attach(io: File.open(Rails.root.join('app/assets/images/test.jpg')),
                  filename: 'test.jpg')
end

結果、「userに使っているimageというメソッドはないよ」と怒られました。

解決策

以下の記述方法を発見し、無事に画像データを持つユーザーのサンプルデータを作成できました。

20.times do |n|
  user = User.create!(
    shop_name: "お店#{ n + 1 }",
    email: "seed#{ n + 1 }@seed.com",
    password: "pass1234",
    password_confirmation: "pass1234",
    category_id: rand(1..10),
    prefecture_id: rand(1..47),
    address: "仮町仮番地123-1",
    business_hours: "9時〜17時",
    holiday: "月曜",
    phone_number: "090-1234-5678",
    image: ActiveStorage::Blob.create_and_upload!(io: File.open(Rails.root.join("db/fixtures/seed.jpg")), filename: "seed.jpg")
  )
end

最後に

ググって出てきた情報の多くは、画像をユーザーを作成した後からattachする場合のやり方で、自分のようにユーザー作成時点で画像が必須という設計とは前提が異なっていました。
なので3つの方法全てがエラーになったんですね。
ちなみに後から画像をattachする方法は、Railsガイドに書いてあります。

解決策のcreate_and_upload!メソッドはこちらに掲載されています。
あまり見たことがない公式リファレンス?だったので、これは初心者には厳しいな、、と言う印象でした。

この記事が誰かの役に立てば幸いです!

補足

seeds.rb ファイルを編集などして、再度サンプルデータを流すときは、以下のコマンドを実行すればデータベースの中身をリセットしてサンプルデータの流し込みまで一括でやってくれます。

% rails db:reset

参考リンク

seeds.rbの画像データの定義の方法がよく分からない

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?