

### 前提・実現したいこと

ウィザード方式の新規会員登録でユーザー情報をdbに登録したいです。

現在、個人開発アプリを作成しております。  
deviceを使ってウィザード方式フォームでユーザー登録を実現しようとしております。  
１ページ目：プロフィール画像や名前など  
２ページ目：住所（住所自動入力含む  
３ページ目：完了ページ

他のモデルを作成する前までは、問題なく登録できていたのですが、  
他のモデルの作成・アソシエーション実装後、dbに保存がされなくなってしまいました。  
（他にもcarrierwaveのインストールなどもしているので、どこを境にできなくなったのかが明確ではありません。）

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

エラー文は特に出ていなかったので、saveからsave!に変更したところ、以下のようなエラー文が表示されました。

[![画像の説明をここに入力](https://i.stack.imgur.com/p1pP9.png)](https://i.stack.imgur.com/p1pP9.png)  
また、コンソールは以下のようにROLLBACKとなってしまっています。

[![画像の説明をここに入力](https://i.stack.imgur.com/JSDBM.png)](https://i.stack.imgur.com/JSDBM.png)

### 該当のソースコード

【registrations_Controller.rb】  
ウィザード方式のフォームに対応するdeviceのコントローラです。

[code]

    # frozen_string_literal: true
    
    class Users::RegistrationsController < Devise::RegistrationsController
      # before_action :configure_sign_up_params, only: [:create]
      # before_action :configure_account_update_params, only: [:update]
    
    
      def new
        @user = User.new
      end
    
      def create
        @user = User.new(sign_up_params)
        unless @user.valid?
          flash.now[:alert] = @user.errors.full_messages
          render :new and return
        end
        session["devise.regist_data"] = {user: @user.attributes}
        session["devise.regist_data"][:user]["password"] = params[:user][:password]
        @address = @user.build_address
        render :new_address
      end
      
      def create_address
        @user = User.new(session["devise.regist_data"]["user"])
        @address = Address.new(address_params)
    
        unless @address.valid?
          flash.now[:alert] = @address.errors.full_messages
          render :new_address and return
        end
        @user.build_address(@address.attributes)
        @user.save!
        session["devise.regist_data"]["user"].clear
        sign_in(:user, @user)
      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
      protected
    
      def address_params
        params.require(:address).permit(:zipcode, :prefecture_code, :city,:district, :building, :room)
      end
    end
    
[/code]

【Application_controller.rb】

[code]

    class ApplicationController < ActionController::Base
      protect_from_forgery with: :exception
      before_action :configure_permitted_parameters, if: :devise_controller?
      def after_sign_in_path_for(resource)
        posts_path
      end
      def after_sign_out_path_for(resource)
        root_path
      end
      protected
    
      def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname,:first_name,:last_name, :first_name_kana, :last_name_kana,:birthday,:image])
      end
    end
    
[/code]

【user.rb】

[code]

    class User < ApplicationRecord
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :validatable
      validates :nickname,:first_name,:last_name, :first_name_kana, :last_name_kana,:birthday,:image ,presence: true
      has_one :address
      has_many :posts
      has_many :messages
      
      has_many :group_users, dependent: :destroy
      has_many :groups, through: :group_users, dependent: :destroy
      include JpPrefecture
      jp_prefecture :prefecture_code
      mount_uploader :image, ImageUploader
    
      def prefecture_name
        JpPrefecture::Prefecture.find(code: prefecture_code).try(:name)
      end
    
      def prefecture_name=(prefecture_name)
        self.prefecture_code = JpPrefecture::Prefecture.find(name: prefecture_name).code
      end
    
    end
    
[/code]

【address.rb】

[code]

    class Address < ApplicationRecord
      belongs_to :user, optional: true
      validates :zipcode, :prefecture_code, :city,:district,presence: true
      mount_uploader :image, ImageUploader
    end
    
[/code]

### 試したこと

■モデル  
・アソシエーションが正しくできていない?

userモデルに関連してくる他のモデルはaddress,post,group,messageです。  
それぞれにhas_many(one)とbelong toの関係がしっかり記述されているか確認した

・外部キーのnilを許可できていない?  
belong_toの記述の後に, optional: trueを追記した

・画像が正しく２ページ目（住所登録）に引き継がれていない?  
正しいかわからないですが、mount_uploader :image, ImageUploaderをaddress.rbにも追記

■コントローラ  
・「Validation failed: Image can't be blank」のためimageが保存できていない？  
application_controllerのdevise_parameter_sanitizerにimageが記載されているか確認

・@address = Address.new(address_params)の下に@address.user = current_userを追記  
他で質問されていたもので、回答になっていたので、こちらも試してみました。

#

初めて、stack overflowを利用させていただきます。  
質問の仕方がわかりにくいなどございましたら、ご教示いただけますと幸いです。  
何卒宜しくお願いいたします。


CC BY-SA 4.0
2020-08-11T13:21:25.900
69463
2020-08-11T14:56:42.233
2020-08-11T14:10:06.183
32986
41469
question
ruby-on-rails ruby database
ウィザード方式の新規会員登録で情報がdbに保存されない


`image` でエラーになっているので、 carrierwave でアップロードされて、まだ save されていない画像が session
経由でちゃんと引き継がれていないようにみえます。

carrierwave で HTTP リクエストをまたいで保存されていない画像を扱うには `image` だけではなく `image_cache`
も必要なので、 `@user.image_cache` も `session` に保存する必要があるのではないでしょうか? (validation
error で hidden に `image_cache` が設定される使い方しかしたことがなくて、すぐに確認できる環境もなかったので、取り出し方は
`@user.image_cache` ではないかもしれません。)

エラーとは直接は関係ないですが、 `regist_data` は `register_data` の方が良さそうです。  
<https://labs.cybozu.co.jp/blog/akky/2005/07/regist/>


CC BY-SA 4.0
2020-08-11T14:56:42.233
69465
2020-08-11T14:56:42.233
14277
69463
answer