我有一个带有某个字段的数据库表,一旦将其插入数据库,就应该无法更新。我如何告诉我的模型它不应该允许更新某个字段?
问问题
12994 次
2 回答
57
你想使用attr_readonly
:
列为只读的属性将用于创建新记录,但更新操作将忽略这些字段。
class Customer < ActiveRecord::Base
attr_readonly :your_field_name
end
于 2009-10-09T09:04:50.700 回答
1
这是我对类似问题的相关解决方案 - 我们有一些字段,我们希望用户能够自己设置,我们在创建记录时不需要它们,但我们不希望它们在设置后被更改。
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
然而,令我惊讶的是它update_attribute
仍然有效,它绕过了验证。没什么大不了的,因为对记录的更新是在实践中大量分配的——但我在测试中指出了这一点,以使其清楚。这里有一些测试。
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
describe '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
于 2019-04-20T11:41:45.637 回答