LoginSignup
6
4

More than 5 years have passed since last update.

[Rails][devise] devise + active_recordで画像を編集する

Posted at

やること

deviseを使用してログイン機能を実装していますが、
ActiveRecordを使用してUserに画像(avatar)を付与しようとした際に
新規登録では画像を付与できたのに編集ではできなかったので
解決方法を書いておこうと思います。

正しいやり方かは知りませんが、僕はこうしました。

前提

今回、Userにimageを付与します。

app/models/user.rb
has_one_attached :image

deviseのStrong Parametersにimageを追加

まずはdeviseのStrong Parametersimageを追加します。

users/registrations_controller
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: :image)
    devise_parameter_sanitizer.permit(:account_update, keys: :image)
  end

この時点で、画像を添付してregistrations#create(新規登録)をすると画像が付与されますが、
registrations#update(編集)を行っても画像は付与されず困ってしまいました。

Railsガイドを見てみると

Active Storage - Railsガイドを参照するとこう書いていました。
https://railsguides.jp/active_storage_overview.html#has-one-attached


既存のuserにavatarを添付するにはavatar.attachを呼び出します。

Current.user.avatar.attach(params[:avatar])

なので、update時にimage.attachを行う必要がある、ということですね。

deviseのStrong Parametersを取り出す

しかし、DeviseのStrongParametersってどうやって取り出すんだろう?と
戸惑ってしまいました。

調べたところ、こうしたらうまくいきました。

users/registrations_controller
  def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    #ここ
    resource.image.attach(account_update_params[:image])

    resource_updated = update_resource(resource, account_update_params)
    yield resource if block_given?
    if resource_updated

  (以下略)


ちなみにこれ、resource_updatedとの順番が逆になるとRecordNotFoundの例外が発生してしまいます。

    resource_updated = update_resource(resource, account_update_params)
    resource.image.attach(account_update_params[:image])

    #この順番だとupdate時に例外が発生

なので、先程の順番で書くようにしてください。

終わり

6
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
6
4