我有一个用户模型,其中有一个文本类型的 friend 列。运行此迁移以使用 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
之前,以下规范通过:
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
方法之前的状态。
使用 Rails 4.0.0.rc2 和 pg 0.15.1
这会是什么?
最佳答案
我怀疑 ActiveRecord 没有注意到您的 friends
array 已更改,因为当您执行以下操作时,底层数组引用不会更改:
self.friends.push(target)
这将改变数组的内容,但数组本身仍然是同一个数组。我知道 postgres_ext gem 会出现这个问题在 Rails3 中给出 this issue :
String attribute isn't marked as dirty, when it changes with
<<
我希望 Rails4 的行为方式相同。
解决方案是创建一个新数组而不是尝试就地修改数组:
update_attributes friends: self.friends + [ target ]
有很多方法可以在向现有数组添加元素的同时创建新数组,您可以使用任何一种。
关于ruby-on-rails - 新数据不会持久保存到 Postgres 上的 Rails 数组列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17283854/