我有用户,帐户和角色模型。角色存储帐户和用户之间的关系类型。
我将attr_accessible
留在Role
空白以防止批量分配漏洞(否则攻击者可能会更改角色类型 - 所有者,管理员等... - ,帐户或用户ID)。
但是如果管理员想要将订户更改为主持人呢?这会引发质量分配安全例外:
user = User.find(params[:id])
role = user.roles.find_by_account_id(params[:account_id])
role.type = "admin"
我该如何解决这个问题?一种方法是创建一个单独的模型来表示每个角色(所有者,管理员,主持人,订阅者)并使用STI类型模式。这让我做:
user = User.find(params[:id])
user.moderatorship.build(account_id: params([:account_id])
乏味!我必须创建Onwership,Moderatorship,Subscribership等,并让他们继承自Role。如果我想坚持单一的角色模型,我怎样才能拥有动态角色而不让自己暴露于大规模分配漏洞?
加分问题:我应该使用用户has_many角色(用户可以为每种角色类型设置一条记录)还是has_one角色(用户只能有一个角色记录,如果他们的角色必须切换角色变化)模式?
class User < ActiveRecord::Base
attr_accessible :name, :email
has_many :accounts, through: roles
end
class Account < ActiveRecord::Base
attr_accessible :title
has_many :users, through: roles
end
class Role < ActiveRecord::Base
attr_accessible
belongs_to: :user
belongs_to: :account
end
答案 0 :(得分:2)
您可以在attr_accessible中使用“as”来拥有不同的分配能力。例如,
attr_accessible :type, as: :admin
然后,当您进行批量作业时,您可以执行类似
的操作@role.update_attributes {type: :moderator}, as: :admin # Will update type
@role.update_attributes {type: :moderator} # Will not update type
答案 1 :(得分:1)
最灵活的方法是覆盖模型类中的mass_assignment_authorizer
方法,以动态更改可访问的属性。
例如:
class Article < ActiveRecord::Base
attr_accessible :name, :content
attr_accessor :accessible
private
def mass_assignment_authorizer
super + (accessible || [])
end
end
现在你可以这样使用它:
@article.accessible = [:important] if admin?
此示例来自RailsCast #237,您可以在其中了解有关此方法的更多信息。
此外,我想向您推荐CanCan gem,它可以帮助您处理角色和能力。