Я бы, вероятно, пошел с подходом трех таблиц. Целостность данных важнее, чем чистота кода.
Если вы хотите, чтобы это выглядело аккуратнее, добавьте виртуальные атрибуты в модели Viewer и Contributor, чтобы они выглядели как локальные атрибуты User. Вы можете сделать его модулем и включить его в модели Viewer и Contributor.
Вы также можете настроить: include =>: user для поиска по умолчанию, чтобы при использовании этих полей вы не получали дополнительный запрос.
У меня сейчас очень кофеин, так что прокомментируйте, если это не имеет смысла:)