Rails:carrierwaveで確認画面から登録フォームに戻った時に画像を残しておきたい
- 評価
- クリップ 0
- VIEW 1,673
前提・実現したいこと
ruby on railsでwebサイトを作っています。
ユーザー登録のプロフィール画像のアップロードに gemのcarrierwaveを利用しております。
登録画面から確認画面を一度挟んで、確認画面で確認ごに登録ボタンを押すことでユーザー情報を登録できるようにしております。登録画面から確認画面に進んだあと、フォームの内容を修正するために一度登録画面に戻る場合やバリデーションに引っかかった場合に、直前にアップした画像をそのまま残しておきたいのですが、画像が消えてしまいもう一度画像をアップしなければなりません。登録画面に戻ったあと、そのまま確認画面に進んだ時に写真をアップしたままにするにはどのように現状のコードを修正したらいいのかわかりません。ご教示をよろしくお願いいたします。
(画像の回転や切り抜きができるようにこちらのサイトも参照して実装してます。
https://tech.recruit-mp.co.jp/server-side/niche-rails-tips/)
登録画面 _form.html.erb
<div class="form-inputs" id="image-cropper">
<div class="col-sm-5">
<%= f.label :profile_img do %>
<span class="label label-danger">必須</span>
プロフィール画像(本人写真)
/ profile picture
<% end %>
<p class="help-block">※待ち合わせの際に顔が分かるように、ご本人様のお写真をご使用ください</p>
</div>
<div class="col-sm-7">
<%= f.file_field :profile_img, accept: 'image/jpeg,image/gif,image/png', class: 'cropit-image-input', required: true %>
<%= f.hidden_field :profile_img_cache %>
<div class="cropit-preview">
<%= image_tag(@user.profile_img.url, class: "vanish") if @user.profile_img? %>
</div>
<div class="controls-wrapper">
<div class="rotation-btns">
<i class="fa fa-undo icon rotate-ccw-btn" aria-hidden="true"></i>
<i class="fa fa-repeat icon rotate-cw-btn" aria-hidden="true"></i>
</div>
<div class="slider-wrapper">
<i class="fa fa-picture-o icon icon-image small-image" aria-hidden="true"></i>
<input type="range" class="cropit-image-zoom-input custom">
<i class="fa fa-picture-o icon icon-image large-image" aria-hidden="true"></i>
</div>
</div>
</div>
<%= f.hidden_field :profile_img_data_uri %>
<%= f.hidden_field :profile_img_data_uri_cache %>
</div>
確認画面 confirm.html.erb
<div class="prof-attr">
<label class="prof-label">
<span class="label label-danger">必須</span>
プロフィール画像(本人写真)
/ profile picture
</label>
<div class="prof-cnt prof-img">
<%= image_tag @user.profile_img.url if @user.profile_img? %>
<%= hidden_field_tag :"cache[profile_img]", @user.profile_img.cache_name %>
</div>
</div>
Controller users_controller.rb
def new
@user = User.new
end
def confirm
@user = User.new(user_params) #POSTされたパラメータを取得
# @user.profile_img.cache!
render :new if @user.invalid?
end
def create
auth = request.env["omniauth.auth"]
if auth.present?
if @auth = Authorization.find_from_auth(auth)
user = @auth.user
log_in user
redirect_back_or user
else
@auth = Authorization.create_from_auth(auth)
user = @auth.user
log_in user
remember(user)
flash[:success] = "ユーザー登録に成功いたしました。"
redirect_back_or user
end
else
@user = User.new(user_params)
begin
@user.profile_img.retrieve_from_cache! params[:cache][:profile_img]
rescue => e
p e
end
if params[:back]
render :new
return
elsif @user.save
@user.send_activation_email
flash[:info] = "アカウントを有効化するために送られてきたメールを確認してください。"
UserHobby.create(:hobby_name => 'オールジャンル', :user_id => @user.id)
redirect_to root_url
return
else
render 'new'
return
end
end
end
モデル user.rb
before_validation :set_profile_img_from_data_uri
・
・
・
def set_profile_img_from_data_uri
if profile_img_data_uri != ''
self.profile_img = data_uri_to_file(profile_img_data_uri)
end
UserHelper users_helper.rb
def data_uri_to_file data_uri
# データURIスキームを正規表現で分割
data = data_uri.try do |uri|
uri.match(%r{\Adata:(?<type>.*?);(?<encoder>.*?),(?<data>.*)\z}) do |md|
{
type: md[:type],
encoder: md[:encoder],
data: Base64.decode64(md[:data]),
extension: md[:type].split('/')[1]
}
end
end
return nil unless data
# 画像のTempfileを作成
temp_file = Tempfile.new('uploaded-data_uri').tap do |file|
file.binmode
file << data[:data]
file.rewind
end
# 画像fileを作成
ActionDispatch::Http::UploadedFile.new(
filename: "data_uri.#{data[:extension]}",
type: data[:type],
tempfile: temp_file
)
end
試したこと
https://github.com/carrierwaveuploader/carrierwave#making-uploads-work-across-form-redisplays
gem carrierwaveの「Making uploads work across form redisplays」を参考に、
hidden_fieldを追加。
確認済みのこと
・登録画面で画像アップロード後、切り抜き前の画像と切り抜いた画像が picture_uploader.rbのcache_dir
で指定したディレクトリで保存されること
ex) uploads/user/profile_img/仮user_id_1/オリジナル画像
uploads/user/profile_img/仮user_id_2/data_uri.png
・本登録ご、picture_uploader.rbのstore_dirで指定したディレクトリで画像ファイルが保存され、DBに data_uri.png(アップした画像の拡張子) という名前でprofile_imgカラムの値が更新されること。
uploads/user/profile_img/user_id/data_uri.png
・確認画面から登録画面に戻った時にはアップした画像は表示されているが、そのまま再び確認画面に進むと画像は表示されません。
環境情報(FW/ツールのバージョンなど)
CentOS Linux release 7.4.1708 (Core) (さくらvps)
ruby: 2.4.3(rbenv)
rbenv 1.1.1-28-gb943955
rails 5.0.6
Phusion Passenger 5.2.3
Apache/2.4.6 (CentOS)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
まだ回答がついていません
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる