Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
129 views
in Technique[技术] by (71.8m points)

New data not persisting to Rails array column on Postgres

I have a user model with a friends column of type text. This migration was ran to use the array feature with postgres:

add_column    :users, :friends, :text, array: true

The user model has this method:

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

The following spec passes until I add user.reload after calling #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

This happens in development as well. The model instance is updated and has the new uid in the array, but once reloaded or reloading the user in a different action, it reverts to what it was before the add_friend method was called.

Using Rails 4.0.0.rc2 and pg 0.15.1

What could this be?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I suspect that ActiveRecord isn't noticing that your friends array has changed because, well, the underlying array reference doesn't change when you:

self.friends.push(target)

That will alter the contents of the array but the array itself will still be the same array. I know that this problem crops up with the postgres_ext gem in Rails3 and given this issue:

String attribute isn't marked as dirty, when it changes with <<

I'd expect Rails4 to behave the same way.

The solution would be to create a new array rather than trying to modify the array in-place:

update_attributes friends: self.friends + [ target ]

There are lots of ways to create a new array while adding an element to an existing array, use whichever one you like.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...