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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

495閲覧

ウィザード形式でDBに保存されない

hayatoganbaru

総合スコア7

MySQL

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

Ruby on Rails

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

0グッド

0クリップ

投稿2021/07/19 11:51

編集2021/07/20 12:02

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
ruby on railsでWebアプリケーションを作成しております。
現在、ユーザー新規登録機能を実装中です。
ユーザー新規登録をウィザード形式を採用しました。
binding.pryでみて見るとしっかりと値は取れてきているのですが、
なぜだかDBに保存されないです。

発生している問題・エラーメッセージ

 パスワードやemailを保存するadmi_usersテーブルと
プロフィールや住所を保存するadmin_profileテーブルを
1対1の関係でアソシエーションを組みました。

該当のソースコード

controllers/admin_users/registrations_controller.rb

# frozen_string_literal: true class AdminUsers::RegistrationsController < Devise::RegistrationsController # before_action :configure_sign_up_params, only: [:create] # before_action :configure_account_update_params, only: [:update] def new @admin_user = AdminUser.new end def create @admin_user = AdminUser.new(sign_up_params) unless @admin_user.valid? render :new and return end session["devise.regist_data"] = {admin_user: @admin_user.attributes} session["devise.regist_data"][:admin_user]["password"] = params[:admin_user][:password] @admin_profile = @admin_user.build_admin_profile render :new_admin_profile end def create_admin_profile @admin_user = AdminUser.new(session["devise.regist_data"]["admin_user"]) @admin_profile = AdminProfile.new(admin_profile_params) unless @admin_profile.valid? render :new_admin_profile and return end @admin_user.build_admin_profile(@admin_profile.attributes) @admin_user.save session["devise.regist_data"]["admin_user"].clear sign_in(:admin_user, @admin_user) end private def admin_profile_params params.require(:admin_profile).permit(:admin_image, :postal_code, :prefecture_id, :municipality, :address, :building_name, :phone_number, :profile) end # GET /resource/sign_up # def new # super # end # POST /resource # def create # super # end # GET /resource/edit # def edit # super # end # PUT /resource # def update # super # end # DELETE /resource # def destroy # super # end # GET /resource/cancel # Forces the session data which is usually expired after sign # in to be expired now. This is useful if the user wants to # cancel oauth signing in/up in the middle of the process, # removing all OAuth session data. # def cancel # super # end # protected # If you have extra params to permit, append them to the sanitizer. # def configure_sign_up_params # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) # end # If you have extra params to permit, append them to the sanitizer. # def configure_account_update_params # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) # end # The path used after sign up. # def after_sign_up_path_for(resource) # super(resource) # end # The path used after sign up for inactive accounts. # def after_inactive_sign_up_path_for(resource) # super(resource) # end end

application_controller.rb

class ApplicationController < ActionController::Base before_action :basic_auth before_action :configure_permitted_parameters, if: :devise_controller? def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:store_name]) end private def basic_auth authenticate_or_request_with_http_basic do |username, password| username == ENV['BASIC_AUTH_USER'] && password == ENV['BASIC_AUTH_PASSWORD'] end end end

models/admin_user.rb

class AdminUser < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable PASSWORD_REGGEX = /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i.freeze validates_format_of :password, with: PASSWORD_REGGEX validates :store_name, presence: true has_many :events has_one :admin_profile end

models/admin_profile.rb

class AdminProfile < ApplicationRecord belongs_to :admin_user, optional: true has_one_attached :admin_image extend ActiveHash::Associations::ActiveRecordExtensions belongs_to :prefecture with_options presence: true do validates :postal_code, format: { with: /\A[0-9]{3}-[0-9]{4}\z/ } validates :prefecture_id, numericality: { other_than: 1, message: "can't be blank"} validates :municipality validates :address validates :phone_number, format: { with: /\A\d{10,11}\z/ } validates :profile validates :admin_image end end

new_admin_profile.html.erb

<%= render "shared/second_header" %> <div class="signup-wrapper"> <div class="signup-main"> <p class="title"> 店舗詳細登録 </p> <%= form_for @admin_profile do |f| %> <%= render 'shared/error_messages', model: f.object %> <div class="container"> <div class="form-box"> <div class="form-text"> イメージ <span class="red">*</span> </div> <div class="click-upload"> <p> クリックしてファイルをアップロード </p> <%= f.file_field :admin_image, id:"profile-image" %> </div> </div> <div class="form-box"> <label for="form-text"> 郵便番号 <span class="red">*</span> </label> <div class="form-right"> <%= f.text_area :postal_code, class:"form-input-box", id:"postal_code", placeholder:"例)123-4567" %> </div> </div> <div class="form-box"> <label for="form-text"> 都道府県 <span class="red">*</span> </label> <div class="form-right"> <%= f.collection_select(:prefecture_id, Prefecture.all, :id, :name, {}, {class:"select-box", id:"profile-prefecture"}) %> </div> </div> <div class="form-box"> <label for="form-text"> 市区町村 <span class="red">*</span> </label> <div class="form-right"> <%= f.text_area :municipality, class:"form-input-box", id:"municipality", placeholder:"例)横浜市緑区" %> </div> </div> <div class="form-box"> <label for="form-text"> 番地 <span class="red">*</span> </label> <div class="form-right"> <%= f.text_area :address, class:"form-input-box", id:"address", placeholder:"例)青山1-1" %> </div> </div> <div class="form-box"> <label for="form-text"> 建物名 </label> <div class="form-right"> <%= f.text_area :building_name, class:"form-input-box", id:"building-name", placeholder:"例)柳ビル 103" %> </div> </div> <div class="form-box"> <label for="form-text"> 電話番号 <span class="red">*</span> </label> <div class="form-right"> <%= f.text_area :phone_number, class:"form-input-box", id:"phone-number", placeholder: "例)09012345678" %> </div> </div> <div class="form-box"> <label for="form-text"> プロフィール <span class="red">*</span> </label> <div class="form-right"> <%= f.text_area :profile, class:"form-text-box", id:"profile" %> </div> </div> <div class="form-box"> <h2 class='form-bottom-text'> 「会員登録」のボタンを押すことにより、 <span>利用規約</span> <br>に同意したものとみなします </h2> </div> <div class='register-btn'> <%= f.submit "会員登録" ,class:"register-submit-btn" %> </div> </div> <% end %> <%= render "shared/footer" %>

試したこと

emailやpasswordの保存を行うadmin_userはmysqlに保存されましたが、
住所やプロフィールの保存を行うadmin_profileは保存されませんでした。

binding.pryをregistrations_controller.rbの
create_admin_profileメソッド内に記述ししてみました。

admin_profile_paramsとターミナルへ入力すると
情報はパラメーターに格納されていますがmysqlへ保存されません。

22: def create_admin_profile => 23: binding.pry 24: @admin_user = AdminUser.new(session["devise.regist_data"]["admin_user"]) 25: @admin_profile = AdminProfile.new(admin_profile_params) 26: unless @admin_profile.valid? 27: render :new_admin_profile and return 28: end 29: @admin_user.build_admin_profile(@admin_profile.attributes) 30: @admin_user.save 31: session["devise.regist_data"]["admin_user"].clear 32: sign_in(:admin_user, @admin_user) 33: end [1] pry(#<AdminUsers::RegistrationsController>)> admin_profile_params => <ActionController::Parameters {"admin_image"=>#<ActionDispatch::Http::UploadedFile:0x00007fb26e526110 @tempfile=#<Tempfile:/var/folders/41/1l2_538s3535cyd3h3y28jj00000gn/T/RackMultipart20210719-6947-12qrix6.jpg>, @original_filename="d62005-2-467583-0.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"admin_profile[admin_image]\"; filename=\"d62005-2-467583-0.jpg\"\r\nContent-Type: image/jpeg\r\n">, "postal_code"=>"123-4567", "prefecture_id"=>"4", "municipality"=>"テスト", "address"=>"テスト", "building_name"=>"テスト", "phone_number"=>"08012345678", "profile"=>"test"} permitted: true>

情報を保存する際に問題があると思うのですが、
変数の定義やスペルミスのチェックをしてみても
特に不備があるように思えませんでした。

どうすればmysqlに保存することができるようになるのでしょうか?
どなたか問題解決のアドバイスをよろしくお願いします!

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

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

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

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

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

guest

回答1

0

ベストアンサー

@admin_user.build_admin_profile(@admin_profile.attributes) @admin_user.save

@admin_user.saveの前にbinding.pryして@admin_userの中身が入っているか確認してみてください。

投稿2021/07/20 12:39

J_O

総合スコア143

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

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

hayatoganbaru

2021/07/21 09:58 編集

ご回答ありがとうございます。 ``` 22: def create_admin_profile 23: @admin_user = AdminUser.new(session["devise.regist_data"]["admin_user"]) 24: @admin_profile = AdminProfile.new(admin_profile_params) 25: unless @admin_profile.valid? 26: render :new_admin_profile and return 27: end 28: @admin_user.build_admin_profile(@admin_profile.attributes) => 29: binding.pry 30: @admin_user.save 31: session["devise.regist_data"]["admin_user"].clear 32: sign_in(:admin_user, @admin_user) 33: end [1] pry(#<AdminUsers::RegistrationsController>)> @admin_profile.attributes => {"id"=>nil, "postal_code"=>"123-4567", "prefecture_id"=>13, "municipality"=>"r", "address"=>"r", "building_name"=>"r", "phone_number"=>"08012345678", "profile"=>"test", "admin_user_id"=>nil, "created_at"=>nil, "updated_at"=>nil} [2] pry(#<AdminUsers::RegistrationsController>)> admin_profile_params => <ActionController::Parameters {"admin_image"=>#<ActionDispatch::Http::UploadedFile:0x00007fbc7f51b1c8 @tempfile=#<Tempfile:/var/folders/41/1l2_538s3535cyd3h3y28jj00000gn/T/RackMultipart20210721-11323-8ldzk7.jpg>, @original_filename="licaxxx.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"admin_profile[admin_image]\"; filename=\"licaxxx.jpg\"\r\nContent-Type: image/jpeg\r\n">, "postal_code"=>"123-4567", "prefecture_id"=>"13", "municipality"=>"r", "address"=>"r", "building_name"=>"r", "phone_number"=>"08012345678", "profile"=>"test"} permitted: true> [3] pry(#<AdminUsers::RegistrationsController>)> @admin_user => #<AdminUser id: nil, store_name: "testtest", email: "test1@gmail.com", created_at: nil, updated_at: nil> ``` とターミナルで返ってきました。 わかりにくくて申し訳ありません。 id=>nilが気になりますが、 アソシエーションも組めています。 どこに着目してエラーを正していけばいいのか アドバイス頂けないでしょうか?
J_O

2021/07/21 17:11 編集

うーん、パッとみた感じおかしいところはなさそうですが、 一度バリデーションのエラーメッセージを取得できるか確認してみてください。 恐らくadmin_userはsaveできて、profileの方だけが弾かれているのはバリデーションかと思うんですが。。。 https://techtechmedia.com/error-messages-validation-rails/
hayatoganbaru

2021/07/22 09:52

引き続きのご回答ありがとうございます。 エラ〜メッセージも確認できました。 class AdminProfile < ApplicationRecord belongs_to :admin_user, optional: true has_one_attached :admin_image extend ActiveHash::Associations::ActiveRecordExtensions belongs_to :prefecture with_options presence: true do validates :postal_code, format: { with: /\A[0-9]{3}-[0-9]{4}\z/ } validates :prefecture_id, numericality: { other_than: 1, message: "can't be blank"} validates :municipality validates :address validates :phone_number, format: { with: /\A\d{10,11}\z/ } validates :profile validates :admin_image end end 何回見直してもおかしいところがないように感じますが、 admin_profileモデルのどこか異変は感じますか?
J_O

2021/07/22 12:09

確認したエラーメッセージを教えてください。
hayatoganbaru

2021/07/22 12:32

申し訳ありません。 エラ〜メッセージを勘違いしておりました。 ターミナルで@admin_profile.errors.full_messagesと入力すると [] が返ってきました。 [5] pry(main)> @admin_profile.errors => #<ActiveModel::Errors:0x00007f957941cf10 @base= #<AdminProfile:0x00007f9579245980 id: nil, postal_code: nil, prefecture_id: nil, municipality: nil, address: nil, building_name: nil, phone_number: nil, profile: nil, admin_user_id: nil, created_at: nil, updated_at: nil>, @details={}, @messages={}> [6] pry(main)> @admin_profile.errors.full_messages => []
J_O

2021/07/22 13:09

下記2点試してください。 1、validates :admin_imageをコメントアウトして、イメージは添付せずに登録してみてください。 2、それぞれのmodelに個別に登録できるか確認してみてください。 ``` def create_admin_profile      ・       ・      ・ render :new_admin_profile and return end @admin_user.save   @admin_profile.user_id = @admin_user.id @admin_profile.save session["devise.regist_data"]["admin_user"].clear ``` 上記でsaveできるようでしたら、ActiveStorageが原因っぽいです。 一度試してみてください。
hayatoganbaru

2021/07/22 13:17

無事saveでき、mysqlにも値が保存されました!! ありがとうございます! 何故activestorageが原因で保存できなかったのでしょうか? また、画像を保存する時にはどのような記述であれば良いのでしょうか?
J_O

2021/07/22 14:48

じゃあactivestorageとvalidationが原因ぽいですね。 一番簡単な方法は、先述した2の方法で登録してみてください。1のバリデーションは元に戻して大丈夫です。 詳細な原因は不明ですが、 activestorageのファイルが保存されるタイミングが、saveトランザクションがコミットされた後に、ストレージに保存されるようなので、それと外部キーのadmin_userをnilの状態で登録しようとしている為、activestorageの保存とadmin_user_idの外部キーのvalidationの関係で保存されなかったのかなーって思っています。
hayatoganbaru

2021/07/24 05:09

返信が遅くなり申し訳ありません。 エラーが発生してしまいました。。 やっぱり画像を投稿する機能は分けたほうがいいですかね。 ActiveRecord::NotNullViolation in AdminUsers::RegistrationsController#create_admin_profile Mysql2::Error: Field 'admin_user_id' doesn't have a default value @admin_user.save @admin_profile.admin_user_id = @admin_user.id @admin_profile.save session["devise.regist_data"]["admin_user"].clear sign_in(:admin_user, @admin_user) end
hayatoganbaru

2021/07/24 09:08

rails sをしたらしっかりと画像も登録されることが確認できました! この度は本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問