Rails ActiveRecord 写入加密属性但不读取它

Rails ActiveRecord writes encrypted attribute but does not read it

我有一个由 patients Postgres 数据库 table 支持的 Patient 模型。它有一个属性 national_id,由密码箱 gem 加密,因此存储在 national_id_ciphertext 列中。这个属性 saved/updated 没问题,我可以在数据库中验证它。

然而,当我读回这条记录时, national_id 属性不包括在内。

Rails 控制台:

pry(main)> p = Patient.find(8)
=> #<Patient id: 8, name: "Øyvind Hansen", address: nil, address_directions: nil, zip: "0667", city: "Oslo", phone_number: "+4712345678", email: "oyvind@test.com", created_at: "2020-09-05 19:41:55", updated_at: "2020-09-05 20:45:46", referral_id: nil>

pry(main)> p.national_id
=> "12345678912"

架构是:

create_table "patients", force: :cascade do |t|
    t.string "name"
    t.string "address"
    t.string "zip"
    t.string "city"
    t.string "phone_number"
    t.string "email"
    t.text "national_id_ciphertext" # Saved, but not retrieved
    t.bigint "referral_id"
    t.index ["referral_id"], name: "index_patients_on_referral_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

Lockbox 加密的实现非常简单,直接来自 the docs 的基本示例。

class Patient < ApplicationRecord
    encrypts :national_id
end

知道为什么 Lockbox 创建的 national_id 访问器不包含在可枚举模型属性中吗?

正如您在自己的测试中指出的那样,该值可用。 national_id 是对象的可用方法,但不是数据库属性。您始终可以使用点符号检索它,例如my_patient.national_id 但不是通过哈希符号

my_patient.national_id
=> "12345678912"

my_patient["national_id"]
=> nil

这通常应该不是问题,只需使用点符号即可。

如果问题是转换为 json,您可以将方法添加到 json 调用中...

my_patient.to_json(methods: [:national_id])

或者您可以修改 to_json 以始终包含它

class Patient < ActiveRecord
   
  def to_json(options={})
    super options.merge({methods: [:national_id]})
  end

end