HABTM 质量分配的替代方案

发布于 2024-10-23 16:36:13 字数 680 浏览 3 评论 0原文

我的情况与已发布的问题类似。 Koraktor 已询问

我正在使用一个简单的用户授权模型,其中包含两个 ActiveRecords 用户和角色 用户和角色彼此之间具有 HABTM 关系。 。 。 使用 @user.roles 或 @user.role_ids 手动分配角色可以,但不能发挥 User#new 或 User#update_attributes 中的“魔力”。

Oleg 建议

attr_accessible :role_ids

将其添加到用户模型中。这将允许批量分配操作员更新角色。然而,出于安全考虑,他警告不要使用这种方法。

我对奥列格的回应有一个后续问题 -

在这种情况下,是否有推荐的方法来更新角色而不使用批量分配?

另外,假设

  1. 您对用户进行身份验证,
  2. 仅允许管理员通过在 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

  1. you authenticate users,
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不知在何时 2024-10-30 16:36:13

批量分配是 Rails 的一个功能,它可以使用更少的代码来更新这样的模型,

Model.create(params[:model])
@model.update_parameters(params[:model])

而不是像这样。

@model.field1 = params[:model][:field1]
@model.field2 = params[:model][:field2]
...
@model.save

但是有了这个功能,就会带来更新我们不想要的值的风险。例如,如果我们只希望用户更新 field1、field2 和 field3,并且您使用 update_parameters 进行批量分配,则如果传递 model[,则存在更新 field4 的风险user][field4]=some_value 通过 url 或任何其他方式。如果我们在代码中显式分配字段,则不会有这种风险。但随后我们必须为每个字段设置值(无论我们在哪里更新或创建),这效率不高。

因此,为了使用批量分配功能,我们有两种选择。首先是 attr_protected

attr_protected :field4

这将保护 field4 免于从 params[:model] 进行批量分配,即使它包含 field4。为了保存 field4,我们必须显式调用 field4 的 setter
代码(@model.field4 =)。但是,attr_protected 的问题是 Rails 可能会提供一些我们可能不知道的用于批量分配的其他属性。例如,如果我们

has_many :model2s

在 Model.rb 中定义,Rails 会自动提供一个方法 model2_ids= ,并且可以通过批量分配来访问该方法。(如果我们给出 model[model2_ids]= > 在 url 中,它将创建关联,根本不是有意的)。因此,使用 attr_protected 时有可能会丢失这样的属性。

因此,推荐的方法是使用 attr_accessible

attr_accessible :field1, :field2, :field3

这将使这些字段开放用于批量分配,而模型中的所有其他属性则不可用于批量分配。因此,推荐的方法是将我们以表单形式提供的属性设置为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

Model.create(params[:model])
@model.update_parameters(params[:model])

instead of

@model.field1 = params[:model][:field1]
@model.field2 = params[:model][:field2]
...
@model.save

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 passing model[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

attr_protected :field4

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 with attr_protected is that Rails may provide some other attributes that we may not know for mass assignment. For example, if we define

has_many :model2s

in Model.rb, Rails will provide a method model2_ids= automatically and this can be accessed by mass assignment.(If we give model[model2_ids]= in the url, it will create associations, not intended at all). So, there is a chance of missing attributes like this while using attr_protected.

So, the recommended method is to use attr_accessible

attr_accessible :field1, :field2, :field3

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 as attr_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 use attr_accessible :role_ids. The alternative would be to assign role_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文