Construction report: we prepare the controller to create and edit the user
Tags: rails
Published: 2021-04-23 19:58:08

I'm already lost as to which post is this. Today a short episode with two actions: login and registration. In [this](https://dev.to/kubacky/extending-the-default-user-devise-4ghm) post we extended the functionality of the default user devise controllers, today we will add some code to them.

One step at a time, we'll start by editing the user registration controller. First, we need to tell our application that we have slightly modified the user model and need different data for registration than the default required. So we add at the beginning of our controller two magic lines that influence what parameters will be required from us by the registration and login form.

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

At this point, we have told our controller that we want to override the default devise actions for the update and create methods. So we need to add two functions:

```ruby 
def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name, :surname, :password, :password_confirmation, :role])
  end

  def configure_account_update_params
    case current_user.role
    when 'trainee'
      trainee_attributes = [:weight, :height, :date_of_birth]
      keys = [:email, :name, :surname, :role, trainee_attributes: trainee_attributes]
    when 'trainer'
      keys = [:email, :name, :surname, :role, trainer_attributes: [:description]]
    end
    
    devise_parameter_sanitizer.permit(:account_update, keys: keys)
  end
```

Both define what fields we want to edit in the form, but it is immediately noticeable that the update function is much more powerful. Why?
While creating a new user requires the same data, regardless of the role, editing looks a little different. The trainee can change his weight or height - this is important for the trainer, and the trainer can change his description - this is important for the trainee. Therefore we have to, depending on the role of the user, require different values in the edit form.

The first subscribers are on their way. They don't know what they're getting into yet.

We still need to distinguish which layout to use for these two actions - we need a different one for logging in and another for editing data where the user is already logged into the application. So we add at the beginning of the controller, after the above two lines with *before_action*

```ruby
layout :resolve_layout
```

And after the two methods written earlier, we add one more

```ruby
  def resolve_layout
    case action_name
    when 'edit'
      'dashboard'
    else
      'application'
    end
  end
```

We will develop these features later, but for now we are satisfied with this state.

In Poland we don't say *'well done'*. We say *'gra gitara'* and I think it's beautiful. The controller we have prepared, in its entirety should look roughly like this:

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

  layout :resolve_layout

  def create
    super do
      case current_user.role
      when 'trainee'
        trainee = Trainee.new(user_id: current_user.id)
        trainee.save
      when 'trainer'
        trainer = Trainer.new(user_id: current_user.id)
        trainer.save
      end
    end
  end

  protected

  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name, :surname, :password, :password_confirmation, :role])
  end

  def configure_account_update_params
    case current_user.role
    when 'trainee'
      trainee_attributes = [:weight, :height, :date_of_birth]
      keys = [:email, :name, :surname, :role, trainee_attributes: trainee_attributes]
    when 'trainer'
      keys = [:email, :name, :surname, :role, trainer_attributes: [:description]]
    end

    devise_parameter_sanitizer.permit(:account_update, keys: keys)
  end

  def resolve_layout
    case action_name
    when 'edit'
      'dashboard'
    else
      'application'
    end
  end
end
```

In the next post we will crate views for these two methods-create and edit user, and install tailwindcss.

Cover photo: It's late, Luna's asleep