2011-02-07 109 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