Rails不保存已更改的属性

Jos*_*ter 2 ruby activerecord attributes ruby-on-rails dirty-data

我将一些文本附加到notes我的某个ActiveRecord::Base模型上的字段中,但是当我保存它时,它不会更新:

valve.notes                          
#=> "Level: Top"

valve.notes << "\nDirection: North"

valve.notes                          
#=> "Level: Top\nDirection: North"

valve.save                           
#=> true

valve.reload.notes                   
#=> "Level: Top"
Run Code Online (Sandbox Code Playgroud)

Jos*_*ter 10

Concat不会告诉ActiveRecord属性已更改.

想出来,想在将来分享给其他人(很可能是我自己!).

我不知道这一点,但ActiveRecord无法确定某个属性在连接时是否已更改(即),或者使用concat()<<.并且因为ActiveRecord仅保存或更新已更改的属性(即),所以它不会更新该属性.

如果你还没有意识到它,这是一个鬼鬼祟祟的小问题,因为它不仅无声地失败,它根本不认为它是失败的(如果你问ActiveRecord的作者,它可能没有).

valve.notes            
#=> "Level: Top"

valve.notes << "\nDirection: North"

valve.changed?         
#=> false

valve.notes_changed?   
#=> false

valve.save
#=> true

valve.reload.notes
#=> "Level: Top"
Run Code Online (Sandbox Code Playgroud)

您可以在Rails的API文档上阅读更多相关信息.

要解决这个问题,您需要做以下两件事之一:

  1. 让ActiveRecord知道notes属性已经改变(即它现在是脏的):

    valve.notes << "\nDirection: North"
    
    valve.changed?                      
    #=> false
    
    valve.notes_will_change!
    
    valve.changed?                      
    #=> true
    
    Run Code Online (Sandbox Code Playgroud)
  2. 不要使用concat()<<附加到您的属性:

    valve.notes = "#{valve.notes}\nDirection: North"
    
    valve.changed?                      
    #=> true
    
    Run Code Online (Sandbox Code Playgroud)

希望至少能帮助另一个灵魂.

J.P