我attr_accessible按照这篇文章使用动态:
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
Run Code Online (Sandbox Code Playgroud)
假设我有一个管理界面,其中包含一个公司的RESTful表单.在此表单上,我有字段employees_attributes,包括用于创建新Employees的空白字段.Employee#accessible=在这种情况下我无法找到一种方法.浏览ActiveRecord源代码,似乎这可能是不可能的:在非常深的调用堆栈的最远端,嵌套关联只会导致Employee.new使用属性调用.
我想过要创建一个可以通过批量分配传递的特殊属性.如果属性的值是正确的代码,则Employee实例将设置@accessible为:all.但我认为没有办法保证在受保护的属性之前设置此属性.
有没有办法让动态受保护的属性与嵌套属性一起使用?
小智 1
在我看来,这就像可以直接从类上的控制器代码针对此请求进行设置。例如
Employee.accessible = :all
Company.create(params[:company])
Employee.accessible = nil
Run Code Online (Sandbox Code Playgroud)
可以将其提取到类似的块中
def with_accessible(*types)
types.flatten!
types.each{|type| type.accessible = :all}
yield
types.each{|type| type.accessible = nil}
end
Run Code Online (Sandbox Code Playgroud)
所以你的最终控制器代码是
with_accessible(Employee, OtherClass, YetAnotherClass) do
Company.create(params[:company])
end
Run Code Online (Sandbox Code Playgroud)
很好地表达了所有属性的情况
对于只有某些属性的情况,我可能会修改为以下内容
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
Run Code Online (Sandbox Code Playgroud)
这给了你
with_accessible(:Employee => [:a, :b, :c], :OtherClass => [:a, :b]) do
Company.create(params[:company])
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
872 次 |
| 最近记录: |