[理想]曲名と曲の画像を投稿するサイトを作っていると仮定する。
inputタグの file uploadではセキュリティの関係上、アップロードしていた画像の初期値を持つことはできないらしい。
しかし、曲名だけ変更したくて画像はそのままで良い時でも、毎回使用されていた画像を探し出してきてアップロードし直さなきゃいけないのはユーザーのストレスになる。
試しに、画像を何も入れずに曲名だけ変更すると、presence trueのvalidationに引っ掛かりエラーになる。
-> 画像を入れ直さなくても他の値が編集できるようになりたい。
[現状]
def update
@item = Item.find(params[:id])
item = ItemsTag.new(item_update_params)
if item.valid?
item.update
@item = Item.find(params[:id])
render :show
else
render :edit
end
end
def update
item = Item.find_by(id: item_id)
item.update(name: name, image: image, description: description, price: price, category_id: category_id, condition_id: condition_id, shipping_fee_person_id: shipping_fee_person_id, region_id: region_id, date_ish_id: date_ish_id, user_id: user_id, id: item_id)
tag = Tag.where(tag_name: tag_name).first_or_initialize
tag.update(tag_name: tag_name)
end
itemsテーブルとtagsテーブルの値がフォームオブジェクトを使って保存しているので、
paramsはformsで定義したupdateメソッドに引き渡され、updateアクションが実行されています。
[方法]
上記の状態で、paramsを見てみると、findメソッドで探した@itemの中には、画像が入っているので、@item.imageと初期値が確認できる。しかし、ItemsTagでインスタンス生成したitemの中には画像が入っていない(active storage上には保存されているがitemsテーブルにもtagsテーブルにも「image」というカラムは存在しないため。)そのため、@itemの中に入ってる画像の初期値を引っ張ってくればオッケー。
if item.image == nil
item.image = @item.image
end
と、「もしitem.imageの値がnilだった時は(=画像を何もアップロードしなかった時)item.imageの値(nil) を @item.image(初期値が入ってる)に上書きする。
という条件分岐をかける。
また、@item.image.blobでは、パラメーターからではなく、activestorageに保存されているデータベースから値を引っ張ってきているのでblobまで記述する必要がある。
def update
@item = Item.find(params[:id])
item = ItemsTag.new(item_update_params)
if item.image == nil
item.image = @item.image.blob
end
if item.valid?
item.update
@item = Item.find(params[:id])
render :show
else
render :edit
end
end
以上です