[英]New data not persisting to Rails array column on Postgres
我有一个带有text类型的friends列的用户模型。 运行此迁移是为了将数组功能与postgres结合使用:
add_column :users, :friends, :text, array: true
用户模型具有以下方法:
def add_friend(target)
#target would be a value like "1234"
self.friends = [] if self.friends == nil
update_attributes friends: self.friends.push(target)
end
通过以下规范,直到我在调用#add_friend
之后添加user.reload
#add_friend
:
it "adds a friend to the list of friends" do
user = create(:user, friends: ["123","456"])
stranger = create(:user, uid: "789")
user.add_friend(stranger.uid)
user.reload #turns the spec red
user.friends.should include("789")
user.friends.should include("123")
end
这也在开发中发生。 模型实例已更新,并且在数组中具有新的uid,但是一旦重新加载或以其他操作重新加载用户,它就会恢复为调用add_friend
方法之前的add_friend
。
使用Rails 4.0.0.rc2和pg 0.15.1
这可能是什么?
我怀疑ActiveRecord不会注意到您的friends
数组已更改,因为,当您执行以下操作时,基础数组引用不会更改:
self.friends.push(target)
这将改变数组的内容 ,但数组本身仍将是同一数组。 我知道这个问题出现在Rails3中的postgres_ext gem并给出了这个问题 :
字符串属性用
<<
更改时,未标记为脏
我希望Rails4的行为相同。
解决方案是创建一个新数组,而不是尝试就地修改该数组:
update_attributes friends: self.friends + [ target ]
有多种方法可在将元素添加到现有数组时创建新数组,无论您喜欢哪种方法。
看来问题可能出在您使用push
修改了数组的位置。
我找不到更主要的自动取款机,但是这篇文章说:
与模型上的数组(或其他可变值)交互时要注意的一件事。 ActiveRecord当前不跟踪“破坏性”或就地更改。 这些包括数组
push
和pop
,advance
DateTime对象。 如果要使用“破坏性”更新,则必须调用<attribute>_will_change!
让ActiveRecord知道您更改了该值。
如果要使用Postgresql数组类型,则必须遵守其格式。 从Postgresql文档输入的格式是
'{10000, 10000, 10000, 10000}'
不是friends.to_s
返回的内容。 在红宝石中:
[1,2,3].to_s => "[1,2,3]"
也就是说,用括号代替大括号。 您必须自己进行转换。
但是,我宁愿依赖ActiveRecord进行序列化(请参阅序列化 )。 数据库不需要知道该值实际上是一个数组,这就是您的域模型泄漏到数据库中。 让Rails做事并封装这些信息。 它已经知道如何对值进行序列化/反序列化。
注意:此响应仅适用于Rails 3,而不适用于Rails4。我将留在这里,以防将来对某人有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.