代码之家  ›  专栏  ›  技术社区  ›  tig Charlie Martin

分配受保护属性的好方法

  •  2
  • tig Charlie Martin  · 技术社区  · 14 年前

    简单部分:

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

    @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 回复  |  直到 14 年前
        1
  •  0
  •   Jimmy Stenke    14 年前

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