Ruby on rails 如何在Rails中使数据库字段为只读?
我有一个带有特定字段的数据库表,一旦它被插入到数据库中,就不可能更新它。如何告诉我的模型不允许更新某个字段?您想使用: 列为只读的属性将用于创建新记录,但更新操作将忽略这些字段Ruby on rails 如何在Rails中使数据库字段为只读?,ruby-on-rails,rails-activerecord,Ruby On Rails,Rails Activerecord,我有一个带有特定字段的数据库表,一旦它被插入到数据库中,就不可能更新它。如何告诉我的模型不允许更新某个字段?您想使用: 列为只读的属性将用于创建新记录,但更新操作将忽略这些字段 class客户
class客户
并且根据定义,该字段在插入时始终是“正确的”(即真实的准确表示)
没有用户在第一次(并且在您的方案中:仅)输入该字段时出错?以下是我针对类似问题的相关解决方案-我们希望用户能够自行设置字段,我们在创建记录时不需要这些字段,但我们不希望在设置后对其进行更改
validate:on::update上禁止更改某些字段
def禁止更改某些字段
返回,除非某些字段更改?
如果某个字段为.nil,则返回?
self.some\u field=某个字段
错误。添加(:某些字段“无法更改!”)
结束
不过,让我吃惊的是,update\u属性仍然有效,它绕过了验证。这没什么大不了的,因为在实践中,对记录的更新是大量分配的——但我在测试中指出了这一点,以澄清这一点。这里有一些测试
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
实际上用户根本不需要输入它,它是由控制器设置的。我要防止的是,有人使用修改后的post请求对其进行修改。在这种情况下,您根本不想弄乱“只读”字段。您要做的是在模型中使用attr\u protected
语句来防止字段被大量更新更改。更好的方法是:使用attr\u accessible
仅使选定字段可用于批量更新。在此处插入:我认为attr\u readonly的正确用法是更改该字段会破坏数据完整性。我有一个字段:valid_at,更改该字段永远不会发生,因为这意味着核心算法出现了严重错误。如果发生这种情况,所有人都在甲板上。所有的数据都可能是坏的。因此,我永远不需要更改它,而是要严防它被其他代码中的错误更改。如果有人试图改变它,我想大声吹。这是你问题的正确答案,但你实际问题的“正确”解决方案有点不同。。。参见对另一个问题的评论。
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