Rails Devise 複数Deviseの親子関係同時登録

1. まずDeviseで複数モデルを作成

rails generate devise user
rails generate devise company

2. routesの設定

devise_for :users, path: 'users'
# eg. http://localhost:3000/users/sign_in
devise_for :companies, path: 'companies'
# eg. http://localhost:3000/admins/sign_in

3認証関係の画面を生成

# config/initializers/devise.rb
config.scoped_views = true
# run
rails g devise:views users
rails g devise:views companies

4コントローラーのカスタマイズ

ここが必ず必要。

rails generate devise:controllers users
rails generate devise:controllers companies

5変更をルーティングに反映

Devise関係のrouteを一番先に書くこと!!

sessions はセッション関係

registrations は登録関係

この2つは必須

 devise_for :companies, path: 'companies', controllers: {
    sessions: 'companies/sessions',
    registrations: 'companies/registrations'
  }
  
  devise_for :users, path: 'users', controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations'
  }

controllers>users>registrations_controller.rb

Deviseでコントローラーを作成

結局ここからはDeviseを使わないということ。

というよりSuperでoverrrideする前に自分のしたい処理を書いておく。

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  # GET /resource/sign_up
  def new
 //関連テーブルもオブジェクトを生成しておく
    @user = User.new
    @user.company = Company.new
    super
    
  end


  # POST /resource
  def create
 //関連テーブルを保存してから、そのidでもって小テーブルを作成
    @company = Company.new()
    @company.email = params[:user][:email]
    @company.password = params[:user][:password]
    @company.save!

    params[:user][:company_id] = @company.id
    
    # params[:user][:name] = "#{params[:user][:name]} #{params[:user][:kana]}"

  //ここからDeviseに任せる
    super
    
  end

本家参考サイト

github.com

application controllerに書きなさい

とあります。

このように書きました。 関連テーブルのストロングパラメータもここに書く。

ここで関連テーブルを許可しておく。

class ApplicationController < ActionController::Base

  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:company_id, :name, :kana])
  end

end

View?? fields_forを回さないと行けないはず?

いいえ、もうdeviseのuser>registration_controllerに記載しているので、Viewでfield_forを回す必要はない。

ついでにtransaction処理を書いておく。userが作成されなかったときに、必要ないcompanyができてしまうので、、

   def create
    
    User.transaction do
  
      @company = Company.new()
      @company.email = params[:user][:email]
      @company.password = params[:user][:password]
      
      # emailとpasswordがないと例外発生
      @company.save!
  
      params[:user][:company_id] = @company.id
      
      # params[:user][:name] = "#{params[:user][:name]} #{params[:user][:kana]}"

          build_resource(sign_up_params)


      # devise
      resource.save!
      
      yield resource if block_given?
      if resource.persisted?
        if resource.active_for_authentication?
          set_flash_message! :notice, :signed_up
          sign_up(resource_name, resource)
          respond_with resource, location: after_sign_up_path_for(resource)
        else
          set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
          expire_data_after_sign_in!
          respond_with resource, location: after_inactive_sign_up_path_for(resource)
        end
      else
        clean_up_passwords resource
        set_minimum_password_length
        respond_with resource
      end
      
    end
    
    # エラー表示
    rescue => e
      set_flash_message! :alert, "#{e.message}" 
      clean_up_passwords resource
      set_minimum_password_length
      
      respond_with resource
  
  end