Ассоциации с ролями с помощью Rolify/Devise/Cancancan

avatar
wayoh22
1 июля 2021 в 17:34
83
1
0

Я где-то читал, что использование Rolify/Devise/Cancancan было лучшей альтернативой настройке двух моделей устройств с функциями входа в систему (с использованием одной страницы входа вместо двух) и их соответствующих связей между другими моделями. Я не понимаю, как установить роли внутри и по-прежнему использовать ассоциации. Например:

Если бы я использовал две модели Devise, они были бы просто...

class Supervisor < ApplicationRecord
  has_many :employees
end

class Employee < ApplicationRecord
  belongs_to :supervisor
end

Но с Rolify я хотел бы сделать следующее:

  1. Администратор — этот пользователь должен иметь возможность устанавливать роли других пользователей
  2. Руководитель - (например, этот пользователь может установить расписание сотрудников)
  3. Сотрудник

Я ошибаюсь? Я знаю, что пример расплывчатый, и я нигде не могу найти ответ о том, как настроить ассоциации с ролями.

Источник

Ответы (1)

avatar
max
1 июля 2021 в 18:56
0

То, что вы ищете, скорее всего, является самореферентной ассоциацией:

class AddSupervisorToUsers < ActiveRecord::Migration[6.1]
  def change
    add_reference :users, :supervisor, 
      null: true, 
      foreign_key: { to_table: :users }
  end
end

class User < ApplicationRecord
  belongs_to :supervisor, 
    class_name: 'User',
    optional: true,
    inverse_of: :employees
  has_many :employees,
    class_name: 'User',
    foreign_key: :supervisor_id,
    inverse_of: :supervisor
end

По сути, это просто ассоциация, указывающая на одну и ту же таблицу. Обратите внимание, что столбец внешнего ключа должен иметь значение NULL, чтобы избежать сценария «курица против яйца», который помешал бы вам создать каких-либо пользователей (если таблица была пустой).

Вы можете сделать это с помощью Rolify:

user.add_role(:supervisor, User.first) # add a role
User.with_role(:supervisor, User.first) # query for supervisors

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

Хотя Rolify — отличный инструмент для некоторых случаев использования, вы можете не захотеть запихивать в него всю свою бизнес-логику.

wayoh22
1 июля 2021 в 19:24
0

Я согласен не класть все яйца в корзину Rolify. Я только что прочитал о STI (наследование одной таблицы), и, похоже, он решил мою проблему прямо сейчас. Он заботится о единственной странице входа и устанавливает роль из того, что я вижу в консоли. Мне нравится идея самореферентных отношений, но, честно говоря, я все еще выясняю ассоциации и не слишком хорошо разбираюсь в этом, поэтому мне, возможно, придется немного поэкспериментировать с этим, но я уверен, что скоро столкнусь с чем-то, но спасибо за ваш вклад!