2

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?

opsb
  • 29,325
  • 19
  • 89
  • 99

1 Answers1

2
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.

François Beausoleil
  • 16,265
  • 11
  • 67
  • 90
  • The property is still readable in the Item class using `read_attribute(:duration)`... Also putting it in a module does not seem to help since the ActiveRecord 'magically' finds the properties, not the self-written classes. – Veger Jan 14 '10 at 16:06
  • Perhaps this is a case of my java day job influencing me. My thinking is that without protecting the property another developer might expect the field to be in use where in fact it isn't. For instance they might create a view that references the description field. Of course on my current rails project there is in fact only 2 of us and we obviously communicate enough for this not to happen. It does leave me with a niggling feeling though, ah well :) – opsb Jan 14 '10 at 17:30