0

Consider I have this following model definition, I want a particular property which should be constant from the moment it has been created

class A
  property :a1, String, :freeze => true
end

Is there something like this? or may be using callbacks ?

Mudassir Ali
  • 7,913
  • 4
  • 32
  • 60
  • You want to have the property assignable only once? Via the initializing attribute hash and or the attribute writer? Should the property value be frozen after first assignment? – mbj Dec 14 '12 at 19:22
  • yes exactly, it should be assignable for the first time after that it shud be frozen – Mudassir Ali Dec 14 '12 at 19:38

2 Answers2

2

Try the following:

class YourModel
  property :a1, String

  def a1=(other)
    if a1 
      raise "A1 is allready bound to a value"
    end
    attribute_set(:a1, other.dup.freeze)
  end
end

The initializer internally delegates to normal attribute writers, so when you initialize the attribute via YourModel.new(:a1 => "Your value") you cannot change it with your_instance.a1 = "your value".. But when you create a fresh instance. instance = YourModel.new you can assign once instance.a1 = "Your Value".

mbj
  • 1,042
  • 9
  • 19
0

If you don't need to assign the constant, then

property :a1, String, :writer => :private

before :create do
  attribute_set :a1, 'some value available at creation time'
end

may suffice

ireddick
  • 8,008
  • 2
  • 23
  • 21
  • I throws this error while creating a new record "private method `type=' called for #", If by some means we can add this attribute after creating the record then it'd suffice, as in after :create do (**make writer private here**) end – Mudassir Ali Dec 12 '12 at 07:34
  • I've updated my answer with how you could initialise the property, but I don't think it's what you want (readable, assign once, must be present) – ireddick Dec 12 '12 at 08:53