Rails 4.1 Postgres String Arrays: Can't save after change

Weirdness:

I am working in rails 4.1 with postgres support. One of my models has several array fields, which I hope are correctly handled by pearl "pg" (0.17.1). My migration file and resulting schema can be found below.

The field in question is a string array. Below I've posted the migration, the resulting schema, and code that doesn't seem to work (along with the output when this code is run in the rails console).

I don't have anything in the User model that references this field.

migration:

add_column :users, :test, :string, :array => true, default: '{}'

      

scheme:

t.string   "test",     default: [], array: true

      

Here are the steps I use to reproduce this in the rails console (assuming a base user model is created to hold the field):

u = User.first()
u.test.push('testValue')

u # => #<User id: 1, name: "dave", passhash: nil, email: nil, created_at: "2014-10-04 10:12:29", updated_at: "2014-10-04 10:12:29", provider: "identity", uid: "1", oauth_token: nil, oauth_expires_at: nil, test: ["testValue"]>

u.save
User.find(1).test # => []

      

So the user record seems to be initialized correctly - it has an empty array set for that field - and I can perform array operations. But somehow I can't get any changes.

FYI, I can modify and save other fields using the same procedure; they are just arrays that behave like this.

Any ideas?

Edit:

u.test.push ('newitem') returns a new array as I expected. No indication that something is wrong, or some error with validates_uniqueness_of - will I see that shooting in the console? Thanks to the first comment, I've now tested with 'update':

u.update(test: [(u.test << 'testValue')].flatten)

      

gives me the behavior I want, but it seems really awkward. Is there something I need to change in the model? I'm not sure if what I'm doing is validates_uniqueness_of fire (it's not set in the model).

+3


source to share


1 answer


There is (at least sometime) a problem with using ruby ​​array operators like push

or <<

in ActiveRecord fields. They are not marked dirty and are not updated in the database by save

. Try the following:

u = User.first()
u.test_will_change!
u.test.push('testValue')
u.save
User.find(1).test

      



attribute_will_change!

marks the attribute as dirty by making sure it gets serialized and stored in the database with save

.

+5


source







All Articles