0

I have the array on my model and set up, and when I go to write the array onto my record it says COMMIT true, yet checking the field on that record immediately after returns an empty array.

Model:

class Feature < ActiveRecord::Base
  serialize :content, Array
  attr_accessible :content
end

Migration:

class AddContentToFeatures < ActiveRecord::Migration
  def change
    add_column :features, :content, :text, array: true, default: []
  end
end

What I tried, along with various symbol and string syntaxes, is this:

> f=Feature.new
> f.content_will_change! #i feel like i shouldn't have to do this
> f.content = ['sadasd','asdasd']
> f.save!
    BEGIN
    COMMIT
=> true
> f.content
=> []

How do I persist the array on the model?

3
  • 1
    I serialize arrays all the time without problems, but the database just assumes a text field, nothing more. I'd rake db:rollback and then remove the array: true, default: [] and then migrate again. @peterkim 's suggestion makes sense to me. Commented Feb 16, 2016 at 21:57
  • @SteveTurczyn But PostgreSQL understands SQL arrays so using the serialize kludge with PostgreSQL is a bit nasty. Commented Feb 17, 2016 at 1:36
  • Sorry, I overlooked the postgresql tag. Either answer works, but the answer by @muistooshort is best one. Commented Feb 17, 2016 at 9:48

2 Answers 2

4

If you're using native PostgreSQL arrays (which you are since you have array: true in your migration) then you shouldn't use serialize at all. serialize is used to store YAML in the database:

serialize(attr_name, class_name_or_coder = Object)

If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, then specify the name of that attribute using this method and it will be handled automatically. The serialization is done through YAML. If class_name is specified, the serialized object must be of that class on assignment and retrieval. Otherwise SerializationTypeMismatch will be raised.

So serialize simply stores a YAML-encoded object inside a text column in the database. But PostgreSQL, ActiveRecord in Rails4, and the underlying PostgreSQL driver all understands arrays without all the YAML unpleasantness.

Leave the array: true in your migration, remove the serialize :content, Array from your model, and it should work fine. As an added bonus, you'll be able to use all of PostgreSQL's array operators and functions to query your content, serialize doesn't allow you to do this.

Sign up to request clarification or add additional context in comments.

Comments

2

The default data structure for Rails' serializer is a Hash which you are not saving into f.content.

To save an Array to the serialized content, try in your Feature Model the following:

serialize :content, Array

4 Comments

hi. I've done it with the array specified as here, as well. I only removed it because it didn't seem to be doing anything. I'm getting the same results whether or not Array is specified. Added to the question tho.
You may want to try to update that migration without the array: true, default: []
yes, that was it, thanks. I wonder why that's in the rails docs... I'll mark this as the answer.
sorry, had to give it to muisshort for the added bonuses doing it that way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.