首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mass_assignment_authorizer和嵌套属性

mass_assignment_authorizer和嵌套属性
EN

Stack Overflow用户
提问于 2011-02-08 04:28:40
回答 2查看 881关注 0票数 6

根据本文,我使用的是动态attr_accessible

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

它工作得很好。但我还没有找到一种优雅的方法来使其与嵌套属性一起工作。下面是一些简化的代码:

代码语言:javascript
复制
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

我曾想过创建一个可以通过批量赋值传入的特殊属性。如果属性的值是正确的代码,Employee实例将把@accessible设置为:all。但我不认为有一种方法可以保证在设置受保护的属性之前设置此属性。

有没有办法让动态受保护的属性与嵌套属性一起工作?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-25 04:03:29

在我看来,这似乎是可以直接从控制器代码中为这个请求在类上设置的东西。例如。

代码语言:javascript
复制
Employee.accessible = :all
Company.create(params[:company])
Employee.accessible = nil

它可以被提取到像这样的块中

代码语言:javascript
复制
def with_accessible(*types)
  types.flatten!
  types.each{|type| type.accessible = :all}
  yield
  types.each{|type| type.accessible = nil}
end

所以你的最终控制器代码是

代码语言:javascript
复制
with_accessible(Employee, OtherClass, YetAnotherClass) do
  Company.create(params[:company])
end

对所有属性的情况有很好的表现力

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

代码语言:javascript
复制
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

这给了你

代码语言:javascript
复制
with_accessible(:Employee => [:a, :b, :c], :OtherClass => [:a, :b]) do
  Company.create(params[:company])
end
票数 1
EN

Stack Overflow用户

发布于 2012-11-09 02:53:37

我刚接触rails,在尝试让嵌套属性工作时遇到了很多麻烦,但我发现我必须将嵌套属性添加到我的可访问列表中。

代码语言:javascript
复制
class Company < ActiveRecord::Base
  has_many :employees

  accepts_nested_attributes_for :employees

  attr_accessible :employees_attributes
end

我的理解是accepts_nested_attributes_for创建了那个特殊的employees_attributes,但是当你将所有属性默认为不可访问时(我相信asciicast就是这样),你将无法使用它。

我希望这能有所帮助。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4926180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档