Rails attr_accessible不适用于:type?

LMH*_*LMH 4 ruby-on-rails single-table-inheritance

我尝试在表单中设置单表继承模型类型.所以我有一个属性选择菜单:类型,值是STI子类的名称.问题是错误日志保持打印:

警告:无法批量分配这些受保护的属性:类型

所以我在模型中添加了"attr_accessible:type":

class ContentItem < ActiveRecord::Base
  # needed so we can set/update :type in mass
  attr_accessible :position, :description, :type, :url, :youtube_id, :start_time, :end_time
  validates_presence_of :position
  belongs_to :chapter
  has_many :user_content_items
end
Run Code Online (Sandbox Code Playgroud)

不改变任何东西,ContentItem仍然具有:在控制器中调用.update_attributes()之后的type = nil.知道如何从表单中大量更新:type?

小智 20

我们可以覆盖attributes_protected_by_default

class Example < ActiveRecord::Base

  def self.attributes_protected_by_default
    # default is ["id","type"]
    ["id"]
  end
end

e = Example.new(:type=>"my_type")
Run Code Online (Sandbox Code Playgroud)


ry.*_*ry. 9

您应该使用基于您要创建的子类的正确构造函数,而不是调用超类构造函数并手动分配类型.让ActiveRecord为您完成此操作:

# in controller
def create
   # assuming your select has a name of 'content_item_type'
   params[:content_item_type].constantize.new(params[:content_item])
end
Run Code Online (Sandbox Code Playgroud)

这为您提供了在子类initialize()方法或回调中定义不同行为的好处.如果您不需要这些类型的好处或者计划经常更改对象的类,您可能需要重新考虑使用继承并坚持使用属性.


LMH*_*LMH 6

railsforum.com上的双工找到了一个解决方法:

在表单和模型中使用虚拟属性而不是类型为dirtectly:

def type_helper   
  self.type 
end 
def type_helper=(type)   
  self.type = type
end
Run Code Online (Sandbox Code Playgroud)

工作就像一个魅力.