4

Here is how I use array in a rails 5 model in migration

  t.text :diagnoses, array: true, default: []

in model

class Patient < ApplicationRecord
  serialize :diagnoses, Array
end

in my seed method I am doing it like

  patient = Patient.create(first_name: 'John', last_name: 'Smith', admission: a)
  patient.diagnoses = [1, 2]
  patient.save!

It give an error as

ActiveRecord::SerializationTypeMismatch: can't dump `diagnoses`: was supposed to be a Array, but was a Integer. -- 0

Thanks for any help!

3
  • Try patient.diagnoses = [1, 2].to_yaml. Commented Oct 6, 2019 at 10:27
  • "Keep in mind that database adapters handle certain serialization tasks for you. For instance: json and jsonb types in PostgreSQL will be converted between JSON object/array syntax and Ruby Hash or Array objects transparently. There is no need to use serialize in this case." This applies to array types as well. api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/… Commented Oct 6, 2019 at 12:25
  • @SebastianPalma I have tried with [1, 2].to_yaml same error Commented Oct 6, 2019 at 17:05

2 Answers 2

2

A while ago, I encountered this exact issue. I found the following workaround:

  • In your migration file:

    t.text :diagnoses, array: true
    
  • Then in model:

    class Patient < ApplicationRecord
      serialize :diagnoses
    
      after_initialize do |patient|
        patient.diagnoses= [] if patient.diagnoses == nil
      end
    end
    
  • The after_initialize callback will be called whenever an Active Record object is instantiated, either by directly using new or when a record is loaded from the database.

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

Comments

0

I would seriously consider actually using a relational database properly instead.

# since diagnosis is highly irregular we most likely need to configure rails 
# to pluralize it correctly
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.irregular 'diagnosis', 'diagnoses'
end

class Patient < ApplicationRecord
  has_many :patient_diagnoses
  has_many :diagnoses, through: patient_diagnoses
end

# this table provides data normalization 
class Diagnosis < ApplicationRecord
  has_many :patient_diagnoses
  has_many :patients, through: patient_diagnoses
end

# this is just a join table
class PatientDiagnosis < ApplicationRecord
  belongs_to :patient
  belongs_to :diagnosis
end

This lets you use the foreign keys to ensure referential integrity and lets you use ActiveRecord Associations instead of just cobbling together something wonky. There are very few actual advantages of using an array type here.

If you still want to use your array column you should not use ActiveRecord::AttributeMethods::Serialization. Its used with plain old varchar / text columns to store YAML strings which are serialized/unserialized in Rails. It is a vestige from the dark days before we had native JSON/array types and really does not have any use today besides in legacy applications.

1 Comment

You make a great point. I had been trying to figure out the best way to add an array column, but I see how that was not the best way to go about it. I wish I would have found this two hours ago.

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.