DEV Community

Cover image for Construction report: we prepare the controller to create and edit the user
Artur
Artur

Posted on

Construction report: we prepare the controller to create and edit the user

I'm already lost as to which post is this. Today a short episode with two actions: login and registration. In this 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.

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  before_action :configure_account_update_params, only: [:update]
Enter fullscreen mode Exit fullscreen mode

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:

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
Enter fullscreen mode Exit fullscreen mode

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

layout :resolve_layout
Enter fullscreen mode Exit fullscreen mode

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

  def resolve_layout
    case action_name
    when 'edit'
      'dashboard'
    else
      'application'
    end
  end
Enter fullscreen mode Exit fullscreen mode

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:

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
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)