1
1

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.

carrierwaveを使って画像を保存する時の名前にidをしない方がいいと感じた内容を残す

Posted at

この記事で書くこと

carrierwave を使った画像アップロード機能で格納するディレクトリや、ファイル名に紐ずくモデルのidを使用していた時に、起きた難しさについて。

結論

モデルごとのプライマリーキーであるidは、勝手にrailsがやってくれるカラムであって、特別な意味、今回であれば画像に関する用途に対して使用するのはよくない。
ユニークな名前にしたいのであれば SecureRandom を使用して image_path_code などの列を作成し、保存した上で重複したファイル名が使われないようにする。もしくは、頻繁に作成されるものでなければ、timestampを使用するなどの方法もある。

起こったこと

以下のモデルのデータを一括でcsvにて大量に作る機能が必要になった。

app/model/animal.rb
class Animal < ApplicationRecord
  mount_uploader :animal_icon,              AnimalIconUploader
end
app/uploaders/animal_icon_uploader.rb
class AnimalIconUploader < ApplicationUploader
  def store_dir
    "uploads/images"
  end
  
  def extension_whitelist
    %w(jpg jpeg png gif)
  end

  def filename
    "animal_img_#{model.id}#{File.extname(original_filename)}" if original_filename.present?
  end
end

csv経由でデータを作ろうとする準備
今回は animals#index に一括登録のインターフェイスを追加することにする。

routing

config/routes.rb
中略
post :animal_bulk_imports, to: 'animals#bulk_import', as: :animal_bulk_imports
中略

view

以下を追加

app/views/animals/index.html.haml
中略

  %section
    .title
      csvから一括で登録する
    = form_tag animal_bulk_imports_path, multipart: true do
     %p
       動物たちのcsvファイル
     = file_field_tag :animal_csv
     = submit_tag 'インポート', class: 'btn btn-default'

中略

controller

app/controllers/animals_controller.rb

class AnimalController < ApplicationController
中略
  def bulk_import
    Animal.bulk_import(params[:animal_csv]) if params[:animal_csv]
    redirect_to animals_path, notice: 'csvによる登録を受け付けました'
  end
  
  private

  def animal_bulk_import_params
    params.require(:bulk_import_animal).permit(:animal_csv)
  end

中略
end

一括でcsvを通じて例えば以下のように画像をセットして保存しようとすると、

animal = Animal.new
# row['animal_icon_url'] には参照可能なurlが記載されているとする
animal.remote_animal_icon_url = row['animal_icon_url']

animal.save

画像に model.id が使用されているので、正しく保存されず、画像を登録することができない。
ということが起きる。

こうなると、どうするのがいい方法なのかわかっていません。。。 :disappointed:

既存データを新しい参照先に書き換えるようなタスクを書いて、既存データを移行してから、対応するしかないのだろうか。。

少なくとも今後作成するアプリケーションでは、画像パスについては model.id を参照しないようにした方がいい、ということを学びました。 :bow:

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?