Rails4 devise登録時にhas_one で紐づけたモデルを同時生成する

deviseを登録するときに同時に別のモデルを生成する時のメモ。

modelを作る

deviseに準ずるUserモデルを作成

rails g devise user
app/models/user.rb
class User < ActiveRecord::Base
  has_one :telephone

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

 

Userモデルに紐づいたtelephoneモデルを作成

rails g model telephone name number user:references
app/models/telephone.rb
class Telephone < ActiveRecord::Base
  belongs_to :user
end    

devisecontrollerのオーバーライド

今回は登録だけなのでregistration_controllerだけを上書き

config/routes.rb
devise_for :users, :controllers => {
    :registrations => 'users/registrations'
  }

ユーザ登録時のルーティングを変更

app/controllers/users/registrations_controller
class Users::RegistrationsController < Devise::RegistrationsController
  def create
    build_resource(sign_up_params)
    
    ## この部分を加えることで関連モデルを自動的に作成してくれるっぽい
    resource.build_telephone  
    
    resource_saved = resource.save
    yield resource if block_given?
    if resource_saved
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_flashing_format?
        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}" if is_flashing_format?
        expire_data_after_sign_in!
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      respond_with resource
    end
  end

end

こんな感じでできるはず。

"build_モデル名"にすると関連モデルが作られる。

has_manyのときは多分違うと思うので使うことがあったら確認する。



細かいところ違うかも。見つけたら修正する。

もっと早く理解できるようにしたい

参考

deviseのgithub
Rails で Devise のコントローラーをカスタマイズ