Как быстро настроить два разных типа пользователей с помощью Rails и Devise.

Иногда нам нужно иметь разные типы пользователей в нашем приложении. Конечно, мы могли бы создать две разные модели разработки и иметь разные процессы регистрации и входа в систему, но есть несколько способов достижения аналогичного результата. В этом руководстве мы рассмотрим наследование одной таблицы (STI) в Rails на пользовательской модели.

Допустим, у нас есть приложение, в котором модель User имеет атрибуты email, password, и другие атрибуты, связанные с Devise, а также first_name и фамилия. Теперь представим, что есть один тип пользователей, которых мы будем называть Клиент, а другой - Продавец. В этом примере клиенты могут зарегистрироваться в приложении, тогда как продавцы создаются владельцами приложения и не могут напрямую зарегистрироваться в веб-приложении.

Первое, что нам нужно сделать, это добавить столбец в таблицу Users с именем type. Это зарезервированный столбец в Rails, используемый для реализации STI, и в нем будет храниться строка с именем класса «Покупатель» или «Продавец».

rails g migration AddTypeToUsers type:string
rails db:migrate

Мы также можем добавить эти два вспомогательных метода в класс User для удобства:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  def customer?
    type == 'Customer'
  end
  def seller?
    type == 'Seller'
  end
end

Затем мы создаем классы Клиент и Продавец, которые наследуются от Пользователь.

# app/models/customer.rb
class Customer < User
  # ...
end
# app/models/seller.rb
class Seller < User
  # ...
end

Несмотря на то, что экземпляры Customer и Seller по-прежнему будут храниться в таблице Users, теперь мы можем использовать интерфейс запросов ActiveRecord прямо из коробки следующим образом:

Customer.all # return all Users of the type Customer
Customer.count # return the number of Customers in the DB
Seller.all # return all Users of the type Seller
Select.count # return the number of Sellers in the DB

Теперь мы переопределим действие контроллера регистрации Devise create, чтобы любой пользователь, который регистрируется через приложение, автоматически относился к типу клиента.

# app/controllers/customers/registrations_controller.rb
class Customers::RegistrationsController < Devise::RegistrationsController
  before_action :configure_permitted_parameters
  def create
    params[:user] = params[:user]&.merge(type: 'Customer')
    super
  end
  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: %i[type])
  end
end

И нам нужно указать маршрутам разработки для использования нашего собственного пользовательского RegistrationsController:

Rails.application.routes.draw do
  devise_for :users, controllers: {
    registrations: 'customers/registrations'
  }
end

Вот и все. Теперь у нас есть система, в которой каждый пользователь, который регистрируется, будет клиентом, а с помощью наследования одной таблицы мы можем добавить поведение, специфичное для клиента или продавца. модель, поместив код в соответствующий класс.