HABTM 质量分配的替代方案
我的情况与已发布的问题类似。 Koraktor 已询问
我正在使用一个简单的用户授权模型,其中包含两个 ActiveRecords 用户和角色 用户和角色彼此之间具有 HABTM 关系。 。 。 使用 @user.roles 或 @user.role_ids 手动分配角色可以,但不能发挥 User#new 或 User#update_attributes 中的“魔力”。
Oleg 建议
attr_accessible :role_ids
将其添加到用户模型中。这将允许批量分配操作员更新角色。然而,出于安全考虑,他警告不要使用这种方法。
我对奥列格的回应有一个后续问题 -
在这种情况下,是否有推荐的方法来更新角色而不使用批量分配?
另外,假设
- 您对用户进行身份验证,
- 仅允许管理员通过在 users_controller 中放置 before_filter 来对用户进行 CRUD,
那么 role_ids 的批量分配仍然是一个有效的问题吗?
I have a similar situation to this question, which was already posted. Koraktor has asked
I'm using a simple model for user authorisation with two ActiveRecords User and Role User and Role have a HABTM relation to each other.
.
.
Manually assigning roles with @user.roles or @user.role_ids works, but not the "magic" inside User#new or User#update_attributes.
Oleg suggested that
attr_accessible :role_ids
be added to the user model. This would allow mass assignment operators to update roles. However, he cautioned against using this approach because of security concerns.
I have a follow up question to Oleg's response -
In this situation, is there a recommended method to update roles without using mass-assignment?
Also, assuming
- you authenticate users,
- only allow administrators to CRUD users by putting a before_filter in the users_controller,
is mass-assignment of role_ids still a valid concern?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
批量分配是 Rails 的一个功能,它可以使用更少的代码来更新这样的模型,
而不是像这样。
但是有了这个功能,就会带来更新我们不想要的值的风险。例如,如果我们只希望用户更新 field1、field2 和 field3,并且您使用 update_parameters 进行批量分配,则如果传递 model[,则存在更新 field4 的风险user][field4]=some_value 通过 url 或任何其他方式。如果我们在代码中显式分配字段,则不会有这种风险。但随后我们必须为每个字段设置值(无论我们在哪里更新或创建),这效率不高。
因此,为了使用批量分配功能,我们有两种选择。首先是 attr_protected
这将保护 field4 免于从 params[:model] 进行批量分配,即使它包含 field4。为了保存 field4,我们必须显式调用 field4 的 setter
代码(
@model.field4 =
)。但是,attr_protected 的问题是 Rails 可能会提供一些我们可能不知道的用于批量分配的其他属性。例如,如果我们在 Model.rb 中定义,Rails 会自动提供一个方法
model2_ids=
,并且可以通过批量分配来访问该方法。(如果我们给出model[model2_ids]=
> 在 url 中,它将创建关联,根本不是有意的)。因此,使用attr_protected
时有可能会丢失这样的属性。因此,推荐的方法是使用 attr_accessible
这将使这些字段开放用于批量分配,而模型中的所有其他属性则不可用于批量分配。因此,推荐的方法是将我们以表单形式提供的属性设置为attr_accessible,以供用户编辑,并且所有其他参数都将受到保护。但是,在使用此功能时,您必须确保已将编辑所需的所有属性包含为
attr_accessible
。就您而言,由于您希望用户编辑
role_ids
并且您仅为管理员用户提供对 CRUD 的访问权限,因此我认为您可以使用attr_accessible :role_ids
。另一种方法是明确分配role_ids
,例如.role_ids = params[:user][:role_ids]
。如果您有另一个不希望用户编辑 role_ids 的表单,则应该使用此选项。Mass assignment is a feature of Rails provided for using less code for updating a model like this
instead of
But with this feature, comes the risk of updating values which we dont intend. For example, if we want just field1, field2 and field3 to be updated by the user and you use
update_parameters
for mass assignment, there is a risk of updating field4, if one is passingmodel[user][field4]=some_value
either from url or by any other ways. If we are explicitly assigning the fields in the code, we do not have this risk. But then we will have to set the values for each field(wherever we are updating or creating) which is not very productive.So, for using the mass assignment feature, we have 2 options. First is
attr_protected
This will protect field4 from being saved from mass assignment from params[:model] even if it contains field4. For saving field4, we have to call the setter for field4 explicitly in
the code(
@model.field4 =
). But, the problem withattr_protected
is that Rails may provide some other attributes that we may not know for mass assignment. For example, if we definein Model.rb, Rails will provide a method
model2_ids=
automatically and this can be accessed by mass assignment.(If we givemodel[model2_ids]=
in the url, it will create associations, not intended at all). So, there is a chance of missing attributes like this while usingattr_protected
.So, the recommended method is to use
attr_accessible
This will make these fields open for mass assignment and all other attributes in the model not available for mass assignment. So, the recommended way is to make those attributes which we are providing in a form for users to edit as
attr_accessible
and all other parameters will be protected. But, while using this you have to make sure you have included all the attributes you need for edit asattr_accessible
.In your case, since you want the user to edit the
role_ids
and you are providing access to CRUD for admin users only, I think you can useattr_accessible :role_ids
. The alternative would be to assignrole_ids
explictely like.role_ids = params[:user][:role_ids]
. You should use this, if you have another form where you dont want the user to edit the role_ids.