Search code examples
ruby-on-railsactiverecordsingle-table-inheritance

single table inheritance: must all classes in hierarchy have same properties?


I have the following

class Item < ActiveRecord::Base
end

class Talk < Item
end

with the migration

class CreateItems < ActiveRecord::Migration
  def self.up
    create_table :items do |t|
      t.string :type
      t.string :name
      t.text :description
      t.time :start_time
      t.time :duration
      t.timestamps
    end
  end

  ...
end

By default the description property will be available on the Item and Talk classes. Is there a way to restrict the property so that is only available to the Talk class?


Solution

  • class Item < ActiveRecord::Base
      def duration
        raise NoMethodError
      end
    
      def duration=(value)
        raise NoMethodError
      end
    end
    
    class Talk < Item
      def duration
        read_attribute(:duration)
      end
    
      def duration=(value)
        write_attribute(:duration, value)
      end
    end
    

    You could always do that, but it's a lot of work for nothing. What's the worst that will happen when you read duration on an Item? You'll get back nil, which will cause a crash shortly thereafter. You don't need to be so concerned about these types of issues in Ruby.

    If needed, you can create a module and include the module in the two classes, for the shared behavior, and drop the STI.