ユーザー属性によってdeviseの新規登録フォームを変える方法


実装したいこと

  • ユーザー属性によって異なるフォームパーツを出力する
    • 会社ユーザーであれば、会社名・email・password
    • 通常ユーザーであれば、email・password
  • 認証周りはdeviseで一括管理したいけれど、むやみにcontrollerやviewを増やしたくない

結論: パラメータで条件分岐

deviseのcontrollerは users 下のものを使用する

routes.rb
devise_for :users, controllers: {
  sessions: 'users/sessions',
  registrations: 'users/registrations',
  passwords: 'users/passwords',
  confirmations: 'users/confirmations'
}
app/controller/users/registrations_controller.rb

# GET /resource/sign_up
def new
  super do |resource|
    if params[:as] == 'company'
      build_resource({})
      self.resource.company = Company.new
    end
  end
end
app/views/users/registrations/new.html.erb
<% if params[:as] == 'company' %>
  <h2 class="has-text-weight-bold">会社アカウント作成</h2>
  <%= f.fields_for :company do |company_form| %>
    <div class="field">
      <%= company_form.label :name, class: 'label has-margin-top is-inline-block' %>
      <span class="has-text-danger">*</span>
      <%= company_form.text_field :name, autofocus: true, class: 'input'  %>
    </div>
  <% end %>
<% end %>

こんな感じで書いておけば、パラメータで companyが渡ってきた時だけ、フォームパーツを出力することができます。

app/controller/application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?

private
def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [company_attributes: [:name]])
end

サインアップの時にパラメータを送信できるよう許可しておく必要があります。

参考: https://github.com/plataformatec/devise#strong-parameters