And*_*ers 11 authentication ruby-on-rails single-table-inheritance devise ruby-on-rails-3
我正在使用Rails 3.2应用程序,我使用Devise进行身份验证.我决定尝试单表继承来管理用户角色,但我很快就遇到了问题.我目前有三个用户模型User < ActiveRecord,Admin < User和Collaborator < User.管理员和协作者共享大多数用户列,但他们的行为和权限略有不同.我的模特目前看起来像这样:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :token_authenticatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :name, :password, :password_confirmation, :remember_me
before_save :ensure_authentication_token
[...]
end
class Admin < User
has_one :account, dependent: :destroy
attr_accessible :account_attributes
accepts_nested_attributes_for :account
end
class Collaborator < User
has_one :account
end
class Account < ActiveRecord::Base
attr_accessible :name
validates_presence_of :name
has_many :projects, dependent: :destroy
has_many :users
end
Run Code Online (Sandbox Code Playgroud)
当我尝试在ProjectController(以及需要身份验证的其他控制器)中验证管理员和协作者时,问题就出现了:
# Causes problem, no one can access anything.
before_filter :authenticate_admin!
before_filter :authenticate_collaborator!
Run Code Online (Sandbox Code Playgroud)
我遇到的类似问题是设计的辅助方法.current_user,现在我有current_admin和current_collaborator,我通过创建一个before过滤器和方法"解决"了这个问题:
def set_current_user
@current_user = current_admin || current_collaborator
end
Run Code Online (Sandbox Code Playgroud)
对于我的Devise身份验证问题,是否有类似或简单的解决方案,或者您是否会推荐另一种方法而不是单表继承,那会是什么?
我的目标是,1.当新用户注册时,他们成为管理员,当他们创建帐户时,还会创建帐户模型.2.然后,新(管理员)用户可以邀请其他用户加入帐户,该帐户将是协作者.3.管理员和协作者应具有不同的权限.注册时,协作者不会创建新的"帐户"(公司可能是我的帐户模型的更好名称),因此管理员和协作者需要稍微不同的表单进行注册和编辑.
谢谢.
更新
我通过创建一个类似的前过滤器来"解决"它:
def authenticate!
if @current_user == current_admin
:authenticate_admin!
elsif @current_user == current_collaborator
:authenticate_collaborator!
end
end
Run Code Online (Sandbox Code Playgroud)
关于可能更优雅的解决方案的建议仍然值得赞赏.
您可以使用以下解决方案解决此问题
def authenticate!
if modelA_user_signed_in?
@current_user = current_modelA
true
else
authenticate_modelB!
end
end
您可以将所有公共逻辑分离到模块中并仅使用同一个表。
module UserMethods
#...
end
class User < ActiveRecord::Base
include UserMethods
devise ...
end
class Admin < ActiveRecord::Base
include UserMethods
self.table_name = "users"
devise ...
end
Run Code Online (Sandbox Code Playgroud)
并在路由、视图中分别配置所有设备模型(如有必要,请参见配置视图)。在这种情况下,您可以轻松处理所有不同的逻辑。