attr_readonly 更新后

attr_readonly After Update

有没有办法在更新后分配attr_readonly

attr_readonly, on: :update

如果没有,也许是一种方法

@post.update(content: params[:content])
@post.readonly 

你可以创建一个before_update

 before_update :forbid_second_update

 def forbid_second_update
   if created_at != updated_at_was
     errors.add :base, "Cannot updated!"
     false
   end
 end

第一次更新将成功,因为 created_at 和 updated_at 将相同

第二次会失败

或者如果您想锁定某些属性并且不想更新失败,您可以添加例如。

 self.email = self.email_was 

这会将 email 属性覆盖为其旧值

您可以像这样在该模型中覆盖 readonly?

def readonly?
  super || created_at != updated_at
end

Rails 在尝试将更新的记录保存到数据库之前检查记录是否只读,如果记录被标记为只读,则会引发 ActiveRecord::ReadOnlyRecord 异常。如果记录至少更改一次(由 updated_atcreated_at 上的不同时间戳表示),则此覆盖的 readonly? 方法通过始终返回 true 来保护记录不被更改两次.

此外,这允许您检查视图 item.readonly? 以隐藏指向编辑页面的链接。

您可以在模型中添加计数

rails g scaffold sport name
rails g migration add_modified_count_to_sports modified_count:integer

我正在分配一个默认值

class AddModifiedCountToSports < ActiveRecord::Migration
  def change
    add_column :sports, :modified_count, :integer, default: 0
  end
end

rake db:migrate

在我的 Sport 模型上,我创建了一个 before_update 类型的验证

class Sport < ActiveRecord::Base

  before_update :validate_update_status

  def validate_update_status
    unless self.modified_count.eql?(1)
        #if the field 'modified_count = 0'
        self.modified_count = 1
    else
        errors.add(:name,'You can only modified your account once')
        false
    end#end unless

  end#def

end#class

您也可以使用像 gem(即 assm)这样的状态机来实现相同的功能 瞧!