2011-02-07 82 views
6

我使用的是动态attr_accessible按这篇文章:mass_assignment_authorizer和嵌套属性

http://asciicasts.com/episodes/237-dynamic-attr-accessible

它工作正常。但是我还没有找到一种使嵌套属性工作的优雅方式。这里有一些简化的代码:

class Company < ActiveRecord::Base 
    has_many :employees 

    accepts_nested_attributes_for :employees 
end 

class Employee < ActiveRecord::Base 
    belongs_to :company 

    attr_protected :salary 

    attr_accessor :accessible 

    def mass_assignment_authorizer 
    if accessible == :all 
     ActiveModel::MassAssignmentSecurity::BlackList.new 
    else 
     super + (accessible || []) 
    end 
    end 
end 

比方说,我有一个管理界面与公司的RESTful形式。在此表格中,我有employees_attributes的字段,其中包括用于创建新员工的空白字段。在这种情况下,我无法找到一种方法来呼叫Employee#accessible=。通过ActiveRecord的源代码浏览,看来,这可能是不可能的:在一个非常深的调用堆栈上最遥远的,嵌套协会只是导致Employee.new被调用的属性。

我还以为有关创建可以通过质量分配传递一个特殊的属性。如果属性的值是正确的代码,员工实例将设置@accessible:all。但我不认为有一种方法可以保证在受保护属性之前设置此属性。

有没有什么办法,使动态保护的属性与嵌套属性的工作吗?

回答

1

这似乎是我喜欢的事,可以直接从您的控制器代码中设置的类此请求。例如。

Employee.accessible = :all 
Company.create(params[:company]) 
Employee.accessible = nil 

这可能是提取块像

def with_accessible(*types) 
    types.flatten! 
    types.each{|type| type.accessible = :all} 
    yield 
    types.each{|type| type.accessible = nil} 
end 

所以你的最终控制代码

with_accessible(Employee, OtherClass, YetAnotherClass) do 
    Company.create(params[:company]) 
end 

漂亮的表现是怎么回事了所有的情况下属性

对于只有某些属性的情况,我可能会将其修改为以下内容

def with_accessible(*types, &block) 
    types.flatten! 
    return with_accessible_hash(types.first, &block) if types.first.is_a?(Hash) 
    types.each{|type| type.accessible = :all} 
    ret = yield 
    types.each{|type| type.accessible = nil} 
    ret 
end 

def with_accessible_hash(hash, &block) 
    hash.each_pair do |klass, accessible| 
    Object.const_get(klass).accessible = accessible 
    end 
    ret = yield 
    hash.keys.each{|type| type.accessible = nil} 
    ret 
end 

,让你

with_accessible(:Employee => [:a, :b, :c], :OtherClass => [:a, :b]) do 
    Company.create(params[:company]) 
end 
2

我新的轨道,而不得不试图让嵌套属性的工作自己的麻烦容载量,但我发现,我不得不添加嵌套属性到我的可访问列表。

class Company < ActiveRecord::Base 
    has_many :employees 

    accepts_nested_attributes_for :employees 

    attr_accessible :employees_attributes 
end 

我的理解是,accepts_nested_attributes_for创建特殊employees_attributes,但是当你默认所有属性不可接近的(我相信asciicast做),你将无法使用它。

我希望有帮助。

+0

是的,你必须employees_attributes添加到您的访问属性列表。但真正的问题是在员工对象本身设置“可访问”属性。请注意,只有当您使用* dynamic *可访问属性时,这才是相关的,如问题开头引用的文章所述。 – rlkw1024 2012-11-08 22:23:56