如何使用模型中的属性在 rails 模型上设置只读?

How to set read-only on a rails model using a attribute within the model?

如果同一模型中的属性设置为 true,我如何在每次访问模型时将其设置为只读?

我到处都看了,只读模型似乎只有很少的文档甚至网络结果。

编辑(附加信息): 我的模型中有两种方法 (application.rb) - 不是私有的

  def lock()
    self.locked = true
    save(validate: false)
  end

  def unlock()
    self.locked = false
    save(validate: false)
  end

我在更新时从我​​的应用程序控制器调用它们:

if params[:application][:locked] == false
  @application.unlock
  return
elsif params[:application][:locked] == true
  @application.lock
  return
end

在模型中 (application.rb) 我有 - 不是私下:

  def readonly?
    locked == true
  end

已更新:

# app/models/application.rb

# I highly suggest renaming `Application` into something else because, Rails
# already has a same defined constant name `Application` which is defined in your
# app/config/application.rb

class Application < ApplicationRecord
  def lock!
    # depending on your use-case I'll do an `update` below instead
    # self.lock = true
    update!(locked: true)
  end

  def unlock!
    # self.lock = false
    update!(locked: false)
  end
end

# app/models/user.rb
class User < ApplicationRecord
  belongs_to :application

  def readonly?
    # this is still subject to race-condition even though already `reloaded`
    application.reload.locked || some_user_attribute == 'HELLO WORLD!'
  end
end

# app/models/comment.rb
class Comment < ApplicationRecord
  belongs_to :application

  def readonly?
    # this is still subject to race-condition even though already `reloaded`
    application.reload.locked || some_comment_attribute_like_is_disabled?
  end
end

请注意,我在那里添加了一个 belongs_to 关联,因为您很可能需要它,因为您所说的 Application 实际上已经是一个普通模型了。如果您没有此关联,并且在内部将 locked 设置为 Application class 的 class 实例变量(即您有 @locked class 实例变量),然后(根据您的要求),您将遇到 1) 持久性问题,因为每个请求(每个不同的 process/server)将默认为 locked = nil(可能会也可能不会对你来说是个问题),还有 2)并发性,因为线程共享这个 class 实例变量的值,这意味着并发请求需要独立评估这个 @locked 值;如果在一个线程中将 @locked 设置为 true,而在另一个线程中 @locked 被覆盖并设置为 false,这将变得有潜在危险。但如果这些都不是问题,我仍然可以更新我的答案以不使用 belongs_to :application;让我知道。