2

简单的部分:

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

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

较难的部分:

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

4

1 回答 1

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_protected和的工作方式相同attr_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))

whereallowed_attributes返回一个数组,如['parent_id', 'published', 'title']

于 2010-07-22T16:36:51.643 回答