分配受保护属性的好方法

时间:2010-07-22 15:26:13

标签: ruby-on-rails attributes protection

简单部分:

我有带有受保护属性的模型,我有行动只能由管理员访问,如何强制分配所有属性,所以我不需要做这样的事情:

@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])
  …

更难的部分:

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

1 个答案:

答案 0 :(得分:0)

好吧,我可以想到两种方法来做到这一点。 首先,在控制器中: 这假设您有一个方法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']

的数组