有一种简单的方法可以将Rails ActiveRecord模型设为只读吗?

bre*_*ish 59 activerecord ruby-on-rails ruby-on-rails-3

我希望能够在数据库中创建一个记录,但后来阻止Rails从那一点开始进行更改.我知道在数据库级别仍然可以进行更改.

我相信attr_readonly在属性级别上做我想要的,但我不想手动指定字段...我宁愿有更多的白名单方法.

此外,我知道有一个:read_only选项用于关联,但我不想限制对象的"readonlyness",如果它是通过关联获取的.

最后,我希望能够仍然销毁一条记录,例如:dependent =>:destroy在关联中起作用.

因此,总结一下:1)允许创建记录,2)允许删除记录,3)防止更改已保留的记录.

scr*_*agz 76

看着ActiveRecord::Persistence,一切都最终create_or_update在幕后呼唤.

def create_or_update
  raise ReadOnlyRecord if readonly?
  result = new_record? ? create : update
  result != false
end
Run Code Online (Sandbox Code Playgroud)

所以!只是:

def readonly?
  !new_record?
end
Run Code Online (Sandbox Code Playgroud)

  • 作为旁注,您可以使用`model.readonly!`为每个实例创建模型 (25认同)
  • 如果你像我一样,你可能想知道为什么要使用`!new_record?`而不是`persisted?`.原因是如果你[正在尝试销毁对象],`persisted?`将返回**false**(https://github.com/rails/rails/blob/4-2-stable/activerecord/lib /active_record/persistence.rb#L99),所以你仍然可以销毁你的只读对象! (8认同)
  • 这也不允许销毁操作 (2认同)

kwa*_*ick 49

我找到了一个更简洁的解决方案,它使用了after_initialize回调:

class Post < ActiveRecord::Base
  after_initialize :readonly!
end
Run Code Online (Sandbox Code Playgroud)

  • 有时您不必这样做,例如记录是否仅由其他应用程序创建 (9认同)
  • 使用此配置,您无法在第一次保存对象. (4认同)
  • 如果您想防止对现有记录的更改,但仍然希望创建和删除,则可以使用`before_update:readonly!`。 (2认同)

Mik*_*wis 26

为什么不在具有只读访问权限的数据库上创建用户,并让rails使用该帐户.

但是,如果要进行模型级访问,可以将以下内容添加到特定模型:

 def readonly?
    true
  end

  def before_destroy
    raise ActiveRecord::ReadOnlyRecord
  end
Run Code Online (Sandbox Code Playgroud)

  • 覆盖 #before_destroy 已被弃用,实际上无济于事。这会起作用: before_destroy :raise_readonly def raise_readonly raise ActiveRecord::ReadOnlyRecord end (2认同)

apn*_*ing 16

此博客文章仍然有效:http://ariejan.net/2008/08/17/activerecord-read-only-models/

基本上,如果添加方法,您可以依赖ActiveRecord的验证:

def readonly?
  true
end
Run Code Online (Sandbox Code Playgroud)


小智 5

TL; DR用于OP

class YourModel < ActiveRecord::Base
  before_save { false } # prevent create & update, allows destroy

  # ... 
end
Run Code Online (Sandbox Code Playgroud)

通常

  • 为了仅防止创建: before_create { false }
  • 仅阻止更新: before_update { false }
  • 仅为了防止破坏: before_destroy { false } # does not prevent delete

另请参阅:http : //guides.rubyonrails.org/active_record_callbacks.html