2011-06-23 46 views
4

我有以下型號:爲什麼不:readonly => true在belongs_to關聯中工作?

class Question < ActiveRecord::Base 

    belongs_to :user, :readonly => true 

end 

我預料的:只讀=> 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 => true會阻止此屬性在初始創建後被更改?如果它不是,那麼readonly選項實際上是做什麼的?

編輯

使用attr_readonly會給非變性(不變性?),我一直在尋找。

class Question < ActiveRecord::Base 

    belongs_to :user 
    attr_readonly :user_id 

end 

與它唯一的問題是,當你嘗試更改屬性,這樣很容易讓蟲子無聲的失敗,它便不會引發異常。

回答

7

從DOC,

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

所以我想阻止你做的事情,如

question.user.name = 'Hacked' 

但讓你繼續修改關係本身。

+0

良好的通話,我檢查了它,你就點上。 –

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 

,或者您可以消除的條件,並使其始終引發異常,然後用新的初始化或創建/更新屬性

+0

我玩過重新定義用戶=。我也訴諸使用attr_readonly做這項工作,但不是很乾淨,因爲它實際上嘗試更新屬性時不會拋出錯誤 –

+0

這看起來不錯,但它打破了我的一個測試:https:/ /gist.github.com/lsiden/8310536。我在Ruby 2.1上使用Rails 4.0.2,並且「belongs_to ...,:attr_readonly => true」打破了模型。需要繼續尋找,但謝謝。 –

0

爲def belongs_to是指id列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

相關問題