I have a database table with a certain field which should be impossible to update once it has been inserted to the database. How do I tell my model that it shouldn't allow updating of a certain field?
You want to use attr_readonly
:
Attributes listed as readonly will be used to create a new record but update operations will ignore these fields.
class Customer < ActiveRecord::Base attr_readonly :your_field_name end
Here's my related solution to a similar problem - we have fields that we want a user to be able to set themselves, we don't require them on creation of the record, but we do NOT want to them be changed once they are set.
validate :forbid_changing_some_field, on: :update def forbid_changing_some_field return unless some_field_changed? return if some_field_was.nil? self.some_field = some_field_was errors.add(:some_field, 'can not be changed!') end
The thing that surprised me, though, was that update_attribute
still works, it bypasses the validations. Not a huge deal, since updates to the record are mass assigned in practice - but I called that out in the tests to make it clear. Here's some tests for it.
describe 'forbids changing some field once set' do let(:initial_some_field) { 'initial some field value' } it 'defaults as nil' do expect(record.some_field).to be nil end it 'can be set' do expect { record.update_attribute(:some_field, initial_some_field) }.to change { record.some_field }.from(nil).to(initial_some_field) end context 'once it is set' do before do record.update_attribute(:some_field, initial_some_field) end it 'makes the record invalid if changed' do record.some_field = 'new value' expect(record).not_to be_valid end it 'does not change in mass update' do expect { record.update_attributes(some_field: 'new value') }.not_to change { record.some_field }.from(initial_some_field) end it 'DOES change in update_attribute!! (skips validations' do expect { record.update_attribute(:some_field, 'other new value') }.to change { record.some_field }.from(initial_some_field).to('other new value') end end end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With