1

如果同一模型中的属性设置为 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
4

1 回答 1

1

更新:

# 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(即您有@locked类实例变量),那么(取决于您的要求),您将遇到 1)持久性问题,因为每个请求(每个不同的进程/服务器)将默认为locked = nil(这可能对您来说是一个问题,也可能不是问题),以及 2)并发性,因为线程共享此类实例变量的值,这意味着同时请求将需要@locked评估此值独立; 如果@locked设置为true在一个线程中,而在另一个线程中@locked被覆盖并设置为false. 但是,如果这些都不是问题,我仍然可以将我的答案更新为不使用belongs_to :application;让我知道。

于 2018-11-26T13:34:57.903 回答