Reputation: 17876
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!
Upvotes: 4
Views: 1455
Reputation: 101891
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.
Upvotes: 0
Reputation:
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.
Upvotes: 2