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

时间:2018-11-26 11:25:13

标签: ruby-on-rails model readonly readonly-attribute

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

1 个答案:

答案 0 :(得分:0)

已更新:

# 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;让我知道。