I’m using dynamic attr_accessible as per this article:
http://asciicasts.com/episodes/237-dynamic-attr-accessible
It works fine. But I haven’t found an elegant way to make it work with nested attributes. Here’s some simplified code:
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
Let’s say I have an admin interface with a RESTful form for a Company. On this form, I have fields for employees_attributes, including blank fields to create new Employees. I can’t find a way to call Employee#accessible= in this context. Browsing through the ActiveRecord source code, it seems that this might be impossible: in the remotest part of a very deep call stack, nested associations just result in Employee.new being called with the attributes.
I’d thought about creating a special attribute that could be passed in through mass assignment. If the attribute’s value were the right code, the Employee instance would set @accessible to :all. But I don’t think there’s a way to guarantee that this attribute gets set before the protected attributes.
Is there any way to make dynamic protected attributes work with nested attributes?
This seems to me like something that could be set directly from your controller code on the class for this request. E.g.
Which could be extracted to a block like
So your final controller code is
Pretty expressive of what’s going on for the case of all attributes
For the case of only certain attributes, I might modify it to the following
Which gives you