Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails attr_accessible does not work for :type?

Im trying set the single table inheritance model type in a form. So i have a select menu for attribute :type and the values are the names of the STI subclasses. The problem is the error log keeps printing:

WARNING: Can't mass-assign these protected attributes: type

So i added "attr_accessible :type" to the model:

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

Doesn't change anything, the ContentItem still has :type=nil after .update_attributes() is called in the controller. Any idea how to mass update the :type from a form?

like image 349
LMH Avatar asked Nov 27 '22 23:11

LMH


2 Answers

we can override 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")
like image 54
user510319 Avatar answered Dec 25 '22 12:12

user510319


You should use the proper constructor based on the subclass you want to create, instead of calling the superclass constructor and assigning type manually. Let ActiveRecord do this for you:

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

This gives you the benefits of defining different behavior in your subclasses initialize() method or callbacks. If you don't need these sorts of benefits or are planning to change the class of an object frequently, you may want to reconsider using inheritance and just stick with an attribute.

like image 26
ry. Avatar answered Dec 25 '22 14:12

ry.