jccsag
jccsag

Reputation: 31

Changing Devise_invitable invite_key_fields to send invitation

So, i'm currently working on an app where I need to allow the admin and teachers of a school to send invitations to new users.

So far so good, I used Devise_invitable and the sending of the invitation token is working. The problem is when I try to add additional fields to the invitation form and write them to the DB. I'm trying to add first_name, last_name and role, but the only thing that gets saved is the email that I write.

NOTE: I'm also trying to store students in a different table than Users table.

I've tried to follow some threads that I saw here that are fairly old and to follow the devise_invitable docs as well. My code is currently as follows:

Users::Invitations controller

class Users::InvitationsController < Devise::InvitationsController
  before_action :configure_permitted_parameters

  def create
    super do |resource|
      if resource.persisted? && resource.role == "aluno"
        AlunoProfile.create(
          set_params
        )
      end
    end
  end

  private

  def set_params
    params.require(:user).permit(
      :first_name,
      :last_name,
      :morada,
      :birthdate,
      :nif,
      :numero_utente,
      :cartao_cidadao,
      :validity,
      :contacto,
      :encarregado_educação,
      :grau_parentesco,
      :contacto_emergencia,
      :aulas,
      :horario_preferencial,
      :recolha_dados,
      :fotografias_captadas
    )
  end

  protected

  # Permit the new params here.
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:invite, keys: [:first_name, :last_name, :role])
  end
end

User Model

class User < ApplicationRecord
  has_many :user_aulas
  has_many :aulas, through: :user_aulas
  has_many :bookings
  has_one :aluno_profile
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :invitable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, invite_for: 2.weeks

  enum role: [:aluno, :professor, :admin]

  after_initialize :set_default_role, :if => :new_record?

  def set_default_role
    self.role ||= :user
  end

  def full_name
    "#{first_name} #{last_name}"
  end
end

Students profile model

class AlunoProfile < ApplicationRecord
  belongs_to :user
end

Invitation view

<h2 class="mx-3 mt-2"><%= t "devise.invitations.new.header" %></h2>

<%= simple_form_for(resource, as: resource_name, url: invitation_path(resource_name), html: { method: :post }) do |f| %>
  <%= f.error_notification %>

  <%= resource.class.invite_key_fields.each do |field| -%>
    <div class="form-inputs mx-3">
      <%= f.input :first_name, input_html: {placeholder: "John"} %>
      <%= f.input :last_name, input_html: {placeholder: "Doe"} %>
      <%= f.input field, input_html: {placeholder: "[email protected]"} %>
      <%= f.input :role, as: :select, collection: [:aluno, :professor], prompt: "Selecionar uma opção", input_html: {class: "form-select"} %>
    </div>
  <% end -%>

  <div class="form-actions mx-3">
    <%= f.button :submit, t("devise.invitations.new.submit_button"), class: 'btn btn-primary' %>
  </div>
<% end %>

Upvotes: 0

Views: 75

Answers (1)

ffscalco
ffscalco

Reputation: 541

As invite_key_fields is a class method from the devise_invitable gem, in your User model, you can overwrite this class method (assuming first_name and last_name attrs are in this model):

def self.invite_key_fields
  %i[email first_name last_name]
end

Upvotes: 0

Related Questions