假設我有兩個ActiveRecord模型:LineItem和Article。通過_id屬性更新AR關聯不會更新關聯對象(驗證前)
class LineItem < ActiveRecord::Base
belongs_to :article
...
end
我遇到上了LineItem(Rails的2.3.11)以下行爲:
>> l = LineItem.new
=> #<LineItem id: nil, article_id: nil, ...>
>> l.article_id=10
=> 10
>> l.article
=> #<Article id: 10, ...>
>> l.article_id=20
=> 20
>> l.article
=> #<Article id: 10, ...>
所以,如果article_id的已經有值,隨後的變化不會改變文章的關聯了。 (至少不是立即 - 只有在保存之後,它才被設置爲新值。)
這在更新現有LineItems時導致我的validate方法出現問題。在我的了LineItem - 控制器我不更新這樣的:
def update
@line_item = LineItem.find(params[:id])
@line_item.attributes = params[:data] #params[:data] contains article_id
...
@line_item.save!
...
end
在我LineItem類我有很多的驗證像這樣(簡化):
def validate
if self.article.max_size < self.size
errors.add_to_base("Too big for chosen article.")
end
end
在更新這個驗證作用於「老」的文章因爲在這一點上,新的只在self.article_id中(但不在self.article中)。在上述條件下,我可以用Article.find(self.article_id)
代替self.article
,但這看起來不像它的意思。
這是一個在rails(2.3.11)中的錯誤還是我做錯了什麼?非常感謝。
謝謝,這是訣竅。備註:雖然傳遞true關聯始終有效,但self.clear_association_cache在上面的irb示例中不起作用,因爲它不作用於新的(未保存的)記錄。但在before_validation回調中使用它通常應該沒問題。 – MichMech
這實際上是一個錯誤,一個非常可怕的錯誤,在互聯網上造成各種各樣的破壞。它固定在3.1或3.2中,但我經常遇到3.0和一些較早版本。如果在_id更改之前引用關聯(在模型過濾器中不常見),則關聯不會更改。 –
@Alex謝謝,我更新了 –