【Rails】carrierwaveでupdateしたときにimageが空でも更新されてしまうのをなんとかする
なんか消える
railsを使っていて、画像のアップロードにはcarrierwaveを使っているのだけど、updateのときに、画像の内容が空でもデータベース内の画像のパスを上書きしてしまうって感じになってる。
つまりパスは最新の日付に従って更新されるのにそれに応じた画像をアップロードしないので実質画像が削除された感じになってしまう。
ということでこれを解消してみた。(もっといい方法はありそうというか使い方が間違ってるからこうなってるのかも)
controller
controllerはこんな感じ。
# app/controller/notes_controller.rb # # omission # before_action :set_note, only: [:show, :edit, :update, :destroy] # # omission # def update if note_params[:coffee_image1] respond_to do |format| if @note.update(note_params) format.html { redirect_to @note, notice: "note was successfully updated with image file" } # format.json { render action: 'edit', status: :created, location: @note } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @note.errors, status: :unprocessable_entity } end end else respond_to do |format| if Note.update_except_for_image_path(note_params) format.html { redirect_to @note, notice: "#{params[:blendName]}note was successfully updated except for image file." } # format.json { render action: 'edit', status: :created, location: @note } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @note.errors, status: :unprocessable_entity } end end end end # omission private def note_params params.require(:note).permit( :blendName, :origin, :place, :date, :roast, :dark, :body, :flavor, :acidity, :sweetness, :cleancup, :aftertaste, :overall, :comment, :coffee_image1 ) end def set_note @note = Note.find(params[:id]) end
冗長だー。完全にDRYに反してるけどどうしたらいいかわからん。htmlとjsonの部分とか、新しいメソッド作ったりすればいいのかな。
とりあえず
if note_params[:coffee_image1]
でnote_paramsにセットした、受け取った値の中にcoffee_image1が含まれているかどうかを確認する。
ユーザが画像データを送っていなかった場合は普通にそのままupdateする。
送っていなかった場合はモデルで自分で定義したクラスメソッドupdate_except_for_image_path
を実行する。
model
上記のクラスメソッドの内容は以下の通り。
def self.update_except_for_image_path(note_params) Note.where(@note).update_all(blendName: note_params[:blendName], origin: note_params[:origin], place: note_params[:place], roast: note_params[:roast], dark: note_params[:dark], body: note_params[:body], flavor: note_params[:flavor], acidity: note_params[:acidity], sweetness: note_params[:sweetness], cleancup: note_params[:cleancup], aftertaste: note_params[:aftertaste], overall: note_params[:overall]) end
update_all
メソッドを使って画像のパス以外のカラムを変更してる。
おわり
入門の入門の参考書だとテーブル内の内容を全部取り出したり、みたいな処理しかしないので全部コントローラで完結してる。
でも実際それは controllerがデータベースの内容を引っ張ってくるロジックを持ってることになるからMVCモデルとしてはあまりよくないみたい。。
ということでどんなデータをselectするか、どんな風にデータをinsertしたりupdateしたいするか、ってロジック部分はできるだけmodelに書くようにこれからも気をつけよう。
できるだけcontrollerをシンプルに保つ。