質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

2回答

1408閲覧

carrierwaveの画像投稿で、画像データがDBに登録されない(インスタンス変数に代入されない)

moai891

総合スコア9

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2020/07/18 05:06

編集2020/07/18 05:08

困っていること

carrierwave + mini_magick + deviseを用いてユーザー登録時にアバター画像を投稿できるようにしたいです。
画像投稿時、ストロングパラメーターは渡っているように見えるのですが、画像データがDBに登録されません。(インスタンス変数に代入されない)

長文となり恐れ入りますが、アドバイス頂ければ幸いです。よろしくお願いいたします。

課題に対するアクション

  • binding.pryを用いたデバッグ

① ストロングパラメーターのうち、[:avatar]のみインスタンス変数@profileに渡っていないように見える

[1] pry(#<Users::RegistrationsController>)> @profile => #<Profile:0x00007fb1b7dd95a8 id: nil, phonenumber: "1118883333", old: 21, job: 1, experience: 1, practice_time: 1, detail: "よろしく", club: "ホゲホゲ", avatar: nil, //問題点。なぜかnil user_id: nil, created_at: nil, updated_at: nil>

②ストロングパラメーターは適切なデータを受け取っていると考えられる

=> <ActionController::Parameters {"phonenumber"=>"1118883333", "old"=>"21", "job"=>"1", "experience"=>"1", "practice_time"=>"1", "detail"=>"よろしく", "club"=>"ホゲホゲ", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x00007fb1b7de7888 @tempfile=#<Tempfile:/var/folders/l9/g98ryfjs4730gx0slq67713r0000gn/T/RackMultipart20200718-27218-1f1z01b.png>, @original_filename="7071b4262c632dc0e7c7660f15459fba.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"profile[avatar]\"; filename=\"7071b4262c632dc0e7c7660f15459fba.png\"\r\nContent-Type: image/png\r\n">} permitted: true>

③@profile.avatarでは画像データが代入されている

=> #<AvatarUploader:0x00007fb1b7dcaff8 @cache_id="1595048033-27925243257579-0005-8319", @cache_storage=#<CarrierWave::Storage::File:0x00007fb1b7dc2b28 @cache_called=nil, @uploader=#<AvatarUploader:0x00007fb1b7dcaff8 ...>>, @file= #<CarrierWave::SanitizedFile:0x00007fb1b7dc9b58 @content=nil, @content_type="image/png", @file="/Users/teranishiyusuke/projects/badsuru/public/uploads/tmp/1595048033-27925243257579-0005-8319/7071b4262c632dc0e7c7660f15459fba.png", @original_filename="7071b4262c632dc0e7c7660f15459fba.png">, @filename="7071b4262c632dc0e7c7660f15459fba.png", @identifier=nil, @model= #<Profile:0x00007fb1b7dd95a8 id: nil, phonenumber: "1118883333", old: 21, job: 1, experience: 1, practice_time: 1, detail: "よろしく", club: "ホゲホゲ", avatar: nil, user_id: nil, created_at: nil, updated_at: nil>, @mounted_as=:avatar, @original_filename="7071b4262c632dc0e7c7660f15459fba.png", @staged=true, @versions={}>

④avatarがnilだからか、@user.save時に、avatarに対するSQL文が発行されていないように見える

[4] pry(#<Users::RegistrationsController>)> exit (11.0ms) BEGIN ↳ app/controllers/users/registrations_controller.rb:34:in `create_profile' User Exists? (13.0ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'raaa@r.com' LIMIT 1 ↳ app/controllers/users/registrations_controller.rb:34:in `create_profile' User Create (17.4ms) INSERT INTO `users` (`nickname`, `email`, `encrypted_password`, `created_at`, `updated_at`) VALUES ('aabbcc', 'raaa@r.com', '$2a$11$HMGyw2YYP9qDzQKbh369PeCcnxGAB5dxLIUO/vwnvqzuiRqK9xwcS', '2020-07-18 04:59:38.775316', '2020-07-18 04:59:38.775316') ↳ app/controllers/users/registrations_controller.rb:34:in `create_profile' Profile Create (16.6ms) INSERT INTO `profiles` (`phonenumber`, `old`, `job`, `experience`, `practice_time`, `detail`, `club`, `user_id`, `created_at`, `updated_at`) VALUES ('1118883333', 21, 1, 1, 1, 'よろしく', 'ホゲホゲ', 4, '2020-07-18 04:59:38.809212', '2020-07-18 04:59:38.809212') ↳ app/controllers/users/registrations_controller.rb:34:in `create_profile' (18.7ms) COMMIT ↳ app/controllers/users/registrations_controller.rb:34:in `create_profile' No template found for Users::RegistrationsController#create_profile, rendering head :no_content Completed 204 No Content in 344980ms (ActiveRecord: 76.7ms | Allocations: 56585)

詳細なコード

  • registration_controller.rb

registration_controller.rb

1# frozen_string_literal: true 2 3class Users::RegistrationsController < Devise::RegistrationsController 4 # before_action :configure_sign_up_params, only: [:create] 5 # before_action :configure_account_update_params, only: [:update] 6 7 # GET /resource/sign_up 8 def new 9 @user = User.new 10 end 11 12 # POST /resource 13 def create 14 @user = User.new(sign_up_params) 15 unless @user.valid? 16 flash.now[:alert] = @user.errors.full_messages 17 render :new and return 18 end 19 session["devise.regist_data"] = {user: @user.attributes} 20 session["devise.regist_data"][:user]["password"] = params[:user][:password] 21 @profile = @user.build_profile 22 render :new_profile 23 end 24 25 def create_profile 26 @user = User.new(session["devise.regist_data"]["user"]) 27 @profile = Profile.new(profile_params) 28 unless @profile.valid? 29 flash.now[:alert] = @user.errors.full_messages 30 render :new_profile and return 31 end 32 @user.build_profile(@profile.attributes) 33 binding.pry 34 @user.save 35 session["devise.regist_data"]["user"].clear 36 sign_in(:user, @user) 37 end 38 # GET /resource/edit 39 # def edit 40 # super 41 # end 42 43 # PUT /resource 44 # def update 45 # super 46 # end 47 48 # DELETE /resource 49 # def destroy 50 # super 51 # end 52 53 # GET /resource/cancel 54 # Forces the session data which is usually expired after sign 55 # in to be expired now. This is useful if the user wants to 56 # cancel oauth signing in/up in the middle of the process, 57 # removing all OAuth session data. 58 # def cancel 59 # super 60 # end 61 62 protected 63 64 def profile_params 65 params.require(:profile).permit(:phonenumber, :old, :job, :experience, :practice_time, :detail, :club, :avatar) 66 end 67 68 # If you have extra params to permit, append them to the sanitizer. 69 # def configure_sign_up_params 70 # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) 71 # end 72 73 # If you have extra params to permit, append them to the sanitizer. 74 # def configure_account_update_params 75 # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) 76 # end 77 78 # The path used after sign up. 79 # def after_sign_up_path_for(resource) 80 # super(resource) 81 # end 82 83 # The path used after sign up for inactive accounts. 84 # def after_inactive_sign_up_path_for(resource) 85 # super(resource) 86 # end 87end
  • profile.rb

profile.rb

1class Profile < ApplicationRecord 2 belongs_to :user, optional: true 3 validates :old, :job, :experience, :phonenumber, :practice_time, presence: true 4 mount_uploader :avatar, AvatarUploader 5end
  • avatar_uploader.rb

avatar_uploader.rb

1class AvatarUploader < CarrierWave::Uploader::Base 2 # Include RMagick or MiniMagick support: 3 # include CarrierWave::RMagick 4 include CarrierWave::MiniMagick 5 6 # Choose what kind of storage to use for this uploader: 7 storage :file 8 # storage :fog 9 10 # Override the directory where uploaded files will be stored. 11 # This is a sensible default for uploaders that are meant to be mounted: 12 def store_dir 13 "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 14 end 15 16 # Provide a default URL as a default if there hasn't been a file uploaded: 17 # def default_url(*args) 18 # # For Rails 3.1+ asset pipeline compatibility: 19 # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 20 # 21 # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 22 # end 23 24 # Process files as they are uploaded: 25 # process scale: [200, 300] 26 # 27 # def scale(width, height) 28 # # do something 29 # end 30 31 # Create different versions of your uploaded files: 32 # version :thumb do 33 process resize_to_fit: [50, 50] 34 # end 35 36 # Add a white list of extensions which are allowed to be uploaded. 37 # For images you might use something like this: 38 # def extension_whitelist 39 # %w(jpg jpeg gif png) 40 # end 41 42 # Override the filename of the uploaded files: 43 # Avoid using model.id or version_name here, see uploader/store.rb for details. 44 # def filename 45 # "something.jpg" if original_filename 46 # end 47end 48
  • 登録フォーム

profile_new.erb.html

1<h2>住所情報登録</h2> 2 3<%= form_for @profile do |f| %> 4 <%= render "devise/shared/error_messages", resource: @profile %> 5 6 <div class="field"> 7 <%= f.label :phonenumber %><br /> 8 <%= f.text_field :phonenumber %> 9 </div> 10 11 <div class="field"> 12 <%= f.label :old %><br /> 13 <%= f.text_field :old %> 14 </div> 15 16 <div class="field"> 17 <%= f.label :job %><br /> 18 <%= f.text_field :job %> 19 </div> 20 21 <div class="field"> 22 <%= f.label :experience %><br /> 23 <%= f.text_field :experience %> 24 </div> 25 26 <div class="field"> 27 <%= f.label :practice_time %><br /> 28 <%= f.text_field :practice_time %> 29 </div> 30 31 <div class="field"> 32 <%= f.label :detail %><br /> 33 <%= f.text_field :detail %> 34 </div> 35 36 <div class="field"> 37 <%= f.label :club %><br /> 38 <%= f.text_field :club %> 39 </div> 40 41 <div class="field"> //画像投稿欄 42 <%= f.label :avatar %><br /> 43 <%= f.file_field :avatar , class: "avatar"%> 44 </div> 45 46 <div class="actions"> 47 <%= f.submit "Sign up" %> 48 </div> 49<% end %> 50 51<%= render "devise/shared/links" %>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Deviseを使ってユーザ登録する場合、password、email以外の項目を追加する場合はDeviseにその旨伝える必要があります。
してますか?
たとえば usernameの追加には以下のようにします。このようなことをどこかでやっていないなら、username を avaterに読み替えて行ってみてください

application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters added_attrs = [ :email, :username, :password, :password_confirmation ] devise_parameter_sanitizer.permit :sign_up, keys: added_attrs devise_parameter_sanitizer.permit :account_update, keys: added_attrs devise_parameter_sanitizer.permit :sign_in, keys: added_attrs end end

投稿2020/07/19 00:11

winterboum

総合スコア23347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moai891

2020/07/19 03:10 編集

ご回答ありがとうございます。 configure_permitted_parametersは実装しております。確かに登録できないとなるとこのファイルが怪しいですね・・・avatarの記述を少し変えなくてはならないでしょうか? ● application.controller.rb class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :phonenumber, :old, :job_id, :experience, :practice_time, :detail, :club, :avatar]) end end
winterboum

2020/07/19 03:52

あるんか、、、、 avatarはそのまま Userテーブルにしまわれるわけではなく、何か通してますよね。 それが関わるかなぁ。 registrationのcreateにて、Userの登録後に改めてavatarだけしまうことが必要なのかもしれませんね
moai891

2020/07/19 05:19 編集

ご返信ありがとうございます。 関係ないかもしれないのですが、コンソールをいじっていたらavatarのみ以下のエラーが出ました。 avatarカラムはstring型で、他のデータと同様なのですが、なぜか保存できないみたいです・・・ carrier waveの仕様なのでしょうか? 9] pry(main)> Profile.new(avatar:2) TypeError: no implicit conversion of nil into String from /Users/teranishiyusuke/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/carrierwave-2.1.0/lib/carrierwave/uploader/cache.rb:190:in `join' ●carrierwave/uploader/cache.rb:190:in `join'のコード def workfile_path(for_file=original_filename) File.join(CarrierWave.tmp_path, @cache_id, version_name.to_s, for_file) ⇦cache.rb:190:in end
winterboum

2020/07/19 05:36 編集

avatarカラムはstring型なんですが、carrier waveによりhuckが定義されてるみたいで、それをアクセスするとcarrier waveの何やらが動いてfileの格納場所だとかURLだとかを持っているobjectが得られます。その辺りの仕掛けを整えるに足る情報が渡らないとエラーになるのだろう、と解釈しています
moai891

2020/07/19 05:49

恐れ入りますが、huckについて教えて詳しく教えて頂くことはできますでしょうか? コンソールで2だけ代入しようとしてもエラーになるのですね・・・
guest

0

自己解決

無理矢理な感じが否めないですが、以下のコードを追加してavatarを追加できるようにしました。

  • registration_controller.rb

registration_controller.rb

1 def create_profile 2 @user = User.new(session["devise.regist_data"]["user"]) 3 @profile = Profile.new(profile_params) 4 unless @profile.valid? 5 flash.now[:alert] = @user.errors.full_messages 6 render :new_profile and return 7 end 8 @user.build_profile(@profile.attributes) 9 @user.save 10 @profile_avatar = Profile.find_by( id: @user.id ) //追加 11 @profile_avatar.update!(avatar: profile_params[:avatar]) ////追加 12 session["devise.regist_data"]["user"].clear 13 sign_in(:user, @user) 14 end

エラーの原因としては、@user.build_profile(@profile.attributes)でオブジェクトを作成後、@user.profile.avatarの値がnilになってしまっているからだと考えられます。

@profile = Profile.new(profile_params)にてProfileモデルオブジェクトを作成した時は、@profile.avatarにて登録データが格納されていたのを確認しました。

しかし、上述の通り@user.build_profile(@profile.attributes)にてオブジェクトを作成した時は、@profile.attributesにて画像格納データ(AvatarUploaderモデルオブジェクト)が作成されなかったようです。

ご協力頂きありがとうごいました。

投稿2020/07/22 12:07

moai891

総合スコア9

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問