Вопрос по ruby-on-rails – Тот же current_user на нескольких моделях в devise
У меня есть модель User и модель Volunteer, которая наследуется от модели User:
<code>class User < ActiveRecord::Base end class Volunteer < User end </code>
Они оба сохраняются в одной таблице в базе данных, но имеют разные контроллеры / маршруты.
Маршруты:
<code>devise_for :users .... devise_for :volunteers .... </code>
И это прекрасно работает, но система авторизации, которую я использую, зависит отcurrent_user
помощник. И это не работает для добровольцев, потому что разработка создаетcurrent_volunteer
для модели Волонтер.
То, что я пытался установитьdevise_for :volunteers, :singular => "user"
, и это создает current_user, который ссылается на пользователей и добровольцев, но проблема в том, что маршруты для добровольцев перепутаны.
Итак, мой вопрос, есть ли способ получитьcurrent_user
помощник, обратитесь к другой модели, кроме пользователя?
возможно, немного поздно, но вы можете попробовать следующее в вашем маршруте.rb
devise_for :users , :skip => :registrations
as :user do
match "volunteers/edit(.:format)", :to => "devise/registrations#edit"
end
devise_for :volunteers , :skip => :sessions
Приведенный выше код предполагает, что все пользователи и его подклассы (при условии, что вы реализуете STI для достижения иерархии модели Users) могут подписывать sign_in и sign_out, но только добровольцы могут зарегистрироваться. Поскольку волонтер является пользователем, пользователь должен иметь возможность редактировать свою регистрацию как таковую. Вы можете добавить больше маршрутов в блоке as: user.
Я принял ответ Виктора Трона, потому что он кажется самым чистым методом.
Однако я решил свою проблему по-другому.
В итоге я жестко запрограммировал процесс входа в систему для других классов:user
, Это дает мне доступ кcurrent_user
метод даже для волонтерского класса.
class Volunteers::SessionsController < Users::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
if resource
flash[:notice] = "You are logged in"
sign_in(:user, resource)
super
else
super
end
end
end
Я столкнулся с подобной проблемой и решил ее так. Но является ли это решение специфичным для канканского драгоценного камня.
application_controlller.rb
def actual_user
@actual_user ||= current_user.present? ? current_user : current_volunteer
end
def current_ability
@current_ability ||= Ability.new(actual_user)
end
Я думаю, что таким образом вы позволите пользователю войти в систему как пользователь и в качестве участника в одном сеансе.
Если у вас есть способ справиться с этим, вы могли бы не просто иметь
# in application_controller.rb
alias_method :devise_current_user, :current_user
def current_user
devise_current_user || current_volunteer
end
в вашем application_controller.rb