为什么不:readonly =>在belongs_to协会上真正的工作?

时间:2011-06-23 15:21:14

标签: ruby-on-rails activerecord

我有以下型号:

class Question < ActiveRecord::Base

  belongs_to :user, :readonly => true

end

我希望:readonly =&gt; true属性会阻止用户进行更改,即

# assume we've set up user_1, user_2 and question 
# and that question.user == user_1

question.user = user_2
question.save
question.reload 
question.user == user_2 # true - why?

为什么这是真的 - 我期望:readonly =&gt; true会阻止在初始创建后更改此属性吗?如果没有那么:readonly选项实际上做了什么?

修改

使用attr_readonly将提供我正在寻找的不可更改性(不变性?)。

class Question < ActiveRecord::Base

  belongs_to :user
  attr_readonly :user_id

end

唯一的问题是,当你尝试更改属性时它永远不会引发异常,因此很容易从静默中获取错误。

3 个答案:

答案 0 :(得分:7)

来自文档,

:readonly
    If true, the associated object is readonly through the association.

所以我认为这会妨碍你做

这样的事情
question.user.name = 'Hacked'

但是让你继续修改关系本身。

答案 1 :(得分:0)

像@christianblais所说,它只影响改变对象的属性,而不是替换它。

以防止在模型中重新定义用户=

class Question < ActiveRecord::Base

  belongs_to :user, :readonly => true

  def user=(new_user)
    if self.user.nil?
      write_attirbute :user_id , new_user.id
    else 
      return false # or raise your prefrence 
    end
end

或者您可以消除条件并使其始终引发异常,然后使用new或create,/ update属性初始化它

答案 2 :(得分:0)

至于 belongs_to 是指id-column def user =(new_user)不会触发但 def user_id =(new_user_id)会做!所以例子是:

class Question < ActiveRecord::Base

  belongs_to :user, :readonly => true

  def user_id=(new_user_id)
    if self.user.nil?
      write_attribute :user_id , new_user_id
    else 
      return false # or raise your preference 
    end
  end
end

在Rails4和ruby 1.9.3上进行了测试