У нас есть приложение с несколькими тентантами, которое очень похоже на подход «с нуля», который объясняет / учит Райан Бейтс.
Аутентификация с нуля.
Мультиарендность с нуля.
У нас есть модель учетной записи, которая имеет атрибут поддомена и использует область видимости для разделения данных.
#ApplicationController
around_filter :scope_current_account
private
def current_account
if request.subdomain.present? && request.subdomain != 'www' && request.subdomain != 'ndt-staging'
@account ||= Account.find_by_subdomain!(request.subdomain)
end
end
helper_method :current_account
def scope_current_account
if request.subdomain.present? && request.subdomain != 'www' && request.subdomain != 'ndt-staging'
Account.current_id = current_account.id
end
yield
ensure
Account.current_id = nil
end
Модели:
#Account.rb
has_many :users, :inverse_of => :account, :dependent => :destroy
#User.rb
belongs_to :account, :inverse_of => :users
default_scope { where(account_id: Account.current_id) }
Мой квест: как лучше всего управлять пользователями приложения в широком масштабе ... то есть User.scoped и User.unscoped?
Первое, что приходит в голову, это добавить атрибут admin_password в модель User. Задайте пароль с помощью переменной среды и при создании пользователя / учетной записи добавьте значение пароля администратора в скрытое поле.
(действие создания учетной записи также создает пользователя и создает учетную запись пользователя)
#AccountsController
def new
@account = Account.new
@account.users.build(params[:user])
end
Самая большая проблема, которую я вижу в этом подходе, - это аутентификация. Мне нужно было бы переписать вещи, чтобы, если admin_password правильный, нормальный атрибут пароля не проверялся. Если admin_password неверен, будет использован атрибут пароля.
В качестве побочного примечания я посмотрел на плагины, такие как actions_as_tenant и devise, но предпочел бы создавать эти части самостоятельно.
Я могу пойти по неправильному пути здесь, поэтому я прошу рекомендовать решения / идеи. Заранее спасибо за это :)
#SessionsController
def create
user = User.find_by_email(params[:email].downcase)
if user && user.authenticate(params[:password])
sign_in user
redirect_to welcome_path
else
flash.now[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end