【问题标题】:Rails 5 , sqlite3 using array as column/ attribute issueRails 5,sqlite3 使用数组作为列/属性问题
【发布时间】:2020-02-03 22:06:46
【问题描述】:

这是我在 rails 5 模型中使用数组的方法 在迁移中

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

在模型中

class Patient < ApplicationRecord
  serialize :diagnoses, Array
end

在我的种子方法中,我正在这样做

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

它给出一个错误

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

感谢您的帮助!

【问题讨论】:

  • 试试patient.diagnoses = [1, 2].to_yaml
  • "请记住,数据库适配器会为您处理某些序列化任务。例如:PostgreSQL 中的 json 和 jsonb 类型将在 JSON 对象/数组语法和 Ruby Hash 或 Array 对象之间透明地转换。有在这种情况下无需使用序列化。”这也适用于数组类型。 api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/…
  • @SebastianPalma 我试过[1, 2].to_yaml同样的错误

标签: ruby-on-rails sqlite serialization ruby-on-rails-5


【解决方案1】:

不久前,我遇到了这个确切的问题。我找到了以下解决方法:

  • 在您的迁移文件中:

    t.text :diagnoses, array: true
    
  • 然后在模型中:

    class Patient < ApplicationRecord
      serialize :diagnoses
    
      after_initialize do |patient|
        patient.diagnoses= [] if patient.diagnoses == nil
      end
    end
    
  • 每当实例化 Active Record 对象时,将调用 after_initialize 回调,无论是直接使用 new 还是从数据库加载记录时。

【讨论】:

    【解决方案2】:

    我会认真考虑真正正确地使用关系数据库。

    # 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
    

    这使您可以使用外键来确保引用完整性,并允许您使用 ActiveRecord 关联,而不仅仅是拼凑一些不可靠的东西。在这里使用数组类型的实际优势很少。

    如果您仍想使用您的数组列,则不应使用ActiveRecord::AttributeMethods::Serialization。它与普通的旧 varchar / text 列一起用于存储在 Rails 中序列化/非序列化的 YAML 字符串。这是在我们拥有原生 JSON/数组类型之前的黑暗时代的遗迹,除了在遗留应用程序中之外,今天真的没有任何用处。

    【讨论】:

    • 你说得很好。我一直试图找出添加数组列的最佳方法,但我发现这不是最好的方法。我希望我能在两个小时前找到这个。
    猜你喜欢
    • 2021-01-23
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2013-11-20
    • 2016-01-04
    相关资源
    最近更新 更多