ruby-on-rails 分配受保护属性的好方法

vx6bjr1n  于 2023-04-22  发布在  Ruby
关注(0)|答案(1)|浏览(195)

简单部分:

我有一个属性为protected的模型,我有一个只能由管理员访问的操作,如何强制分配所有属性,所以我不需要这样做:

@post = Post.find(params[:id])
if params[:post].is_a?(Hash) && params[:post][:published]
  @post.published = params[:post].delete(:published) # delete is to skip warning about protected attribute assignment in update_attributes
end
if @order.update_attributes(params[:post])
  …

难点:

我有一个模型,有很多受保护的属性和多种类型的用户,其中一些只能分配不受保护的属性,一些只能更改部分受保护的属性,一些可以更改所有属性。在这种情况下,如何编写小的可读代码而不重新发明轮子?

zu0ti5jz

zu0ti5jz1#

好吧,我可以想到两种方法。第一,在控制器中:这里假设您有一个方法permitted_to?,该方法检查是否允许用户更改该属性

if params[:post]
  params[:post].each_pair do |key, value|
    @post.send("#{key.to_s}=", value) if @current_user.permitted_to?(:update_attribute, :post, key.to_sym)
  end
  @post.save
end

另一种方法,可能不是最好的方法,因为您将更改类的属性,这意味着它将影响模型的所有示例。
无论如何,假设您使用attr_accessible来限制属性:
在您的模型中,执行以下操作:

accessible_attributes = self.class.inheritable_attributes.delete(:attr_accessible)

然后再恢复它可能是个好主意。

self.class.inheritable_attributes.delete(:attr_accessible) = accessible_attributes

这与attr_protectedattr_readonly的工作方式相同
对于第二部分,我假设每个用户类型都有一个数组,其中包含他们可以更改的属性。
例如:

self.class.inheritable_attributes[:attr_accessible] = 
      Set.new(@current_user.allowed_attributes(:post))

self.class.inheritable_attributes[:attr_protected] = 
      Set.new(@current_user.restricted_attributes(:post))

其中allowed_attributes返回类似['parent_id', 'published', 'title']的数组

相关问题