views:

113

answers:

1

Let's say I have an invoice class that has many items related to it. How can I make sure that after the invoice is saved no items can be added or deleted from the invoice?

I already use the immutable attributes plugin to handle regular fields but it doesn't handle associations. Using attr_readonly doesn't work either.

A: 

has_many has a :readonly option, which makes all items of the collection immutable (api-link). However, unfortunately, this doesn't seem to prevent creation of new items.

class Invoice
  has_many :items, :readonly => true
end

To really make the collection immutable from within the Invoice class, you can redefine the items accessor and #freeze the collection for existing records:

class Invoice
  def items_with_immutability
    items = items_without_immutability
    items.freeze unless new_record?
    items
  end
  alias_method_chain :items, :immutability
end
Andreas
That indeed prevents me from adding new items using << and friends. However, I can still call destroy on the associated items. :readonly => true only prevents saving, which is rather odd.
Andreas