1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ウィザード形式でデータを保存できない‥

Last updated at Posted at 2021-08-01

こんにちは
オリアプ作成中に思うような実装にならなかったので
メモの代わりに記事にしました。

実装したい機能

ユーザー新規登録を行う際に、
admin_usersテーブルと詳細なプロフィールの
投稿を行うadmin_profilesテーブルを生成しました。

admin_usersテーブル

t.string :store_name,         null: false
t.string :email,              null: false, default: '', unique: true
t.string :encrypted_password, null: false, default: ''

admin_profilesテーブル

      t.string     :postal_code,          null: false
      t.integer    :prefecture_id,        null: false
      t.string     :municipality,         null: false
      t.string     :address,              null: false
      t.string     :building_name
      t.string     :phone_number,         null: false
      t.text       :profile,              null: false
      t.references :admin_user,           null: false

AdminUserモデル

  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

AdminProfileモデル

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

AdminProfileモデルで has_one_attached :admin_image
記述しているのは、ActiveStrageを用いてプロフィール画像を
保存したいからです。

admin_userとadmin_profileは1対1の関係で
admin_user has many admin_profile
admin_profile belongs_to admin_user

このadmin_usersテーブルとadmin_profilesテーブルを使用して
ユーザー登録機能をウィザード形式で実装することを試みました。

エラー表示は起こらないのにデータが保存されない‥

admin_users/registrations_controller

 def new
    @admin_user = AdminUser.new
  end

  def create
    @admin_user = AdminUser.new(sign_up_params)
    render :new and return unless @admin_user.valid?

    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)
    render :new_admin_profile and return unless @admin_profile.valid?

    @admin_user.build_admin_profile(@admin_profile)
    @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

まじで辛かったです。
2週間ほど悩み倒しました。
エラーにはならないしbinding.pryしてみても
paramsにデータは入ってたので
データを保存する段階で何か不備が起きていたのだろうとは思ってましたが、
それがなかなか見つからず‥。

ActiveStroageが邪魔してる

詳細な原因は不明ですが、どうやらActiveStrageがデータの保存の
邪魔をしてたみたいです。
ActiveStrageのファイルが保存されるタイミングって、saveトランザクションが
コミットされた後だそうです。
コミットされた後に保存しようとするから外部キーのadmin_userを
nilの状態で登録しようとしてしまい、ActiveStrageの保存と
admin_user_idの外部キーのvalidationの関係で
保存されなかった説が濃厚です。

なので、
admin_users/registrations_controllerの

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

これを

    @admin_user.save
    @admin_profile.admin_user_id = @admin_user.id
    @admin_profile.save

に変更してやったら無事全て保存することができました!!

1
1
1

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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?