Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在Rails中使数据库字段为只读?_Ruby On Rails_Rails Activerecord - Fatal编程技术网

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