我有带有受保护属性的模型,我有行动只能由管理员访问,如何强制分配所有属性,所以我不需要做这样的事情:
@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])
…
我的模型包含许多受保护的属性和多种类型的用户,其中一些只能分配不受保护的属性,有些只能更改部分受保护的属性,有些可以更改所有属性。如何在不重新发明轮子的情况下编写小的可读代码?
答案 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_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))
其中allowed_attributes
返回类似['parent_id', 'published', 'title']