主动记录中序列化的力量
#网络开发人员 #教程 #database #rails

使用Rails的好处是,它允许我们使用主动记录来创建有组织的信息数据库。使用客户端服务器通信,用户可以请求数据并将其返回并显示在浏览器中。用户会触发事件(点击一个类似的按钮,提交表单以及不断提交)。请求信息和/或使用提取请求发送。此提取请求最少包括一个HTTP动词,例如GET,POST,PAST,PATCH和DELETE和一个包括域名和路径的URL。如果发送信息,则通常包含在包含方法的配置对象中(上述http动词,除了get deg deg get n how houns holly how how how how get n hous ht ht hter offect-type type offection/json eppaction/json eft get det get n get n http动词) “}发送JSON数据,以及一个包含转换为JSON的数据(JSON.STRINGIFY(COUNSS))。一旦实现了承诺,返回JSON数据。

我将深入研究此JSON数据的返回方式。基本上,我将谈论序列化的力量。自从我发现串行序列以来,我感到很强大。

I got the power

,但要认真考虑使用序列化器是一种自定义数据显示在后端显示方式的好方法。我将简要讨论如何实现这一目标,并显示我自己项目的示例。让我们从定义序列化开始。数据序列化是将数据转换为可以共享(通过网络)或存储(在文件,内存或数据库中)的格式的过程,然后将其转换回其原始结构。

Image description

出于我们的目的,序列化正在采用我们的JSON输出,并以期望的方式格式化它,以促进在前端(客户端)上使用此数据。

首先,我们需要设置后端,以允许我们使用串行器。可以在我们的控制器中进行序列化,但是它可能会变得复杂且繁琐,尤其是在模型包含许多属性的情况下。连续化器允许分开关注点,这意味着当控制器与我们的模型渲染数据时,串行序列化确定数据的显示方式。 ActiveModel :: Serializer(或AMS)提供了一种简便的方法来自定义控制器的JSON构建方式。

由于Ruby是关于宝石的,猜猜是什么?我们将安装另一个宝石。让我们在Gemfile中为序列化器安装宝石。

# Gemfile
#...
gem 'active_model_serializers'

现在在您的控制台中运行bundle install。接下来,通过运行命令rails g serializer your-model-name为模型生成序列化器。假设我们的模型名称是“模型”。刚刚生成的序列化器看起来像这样。在这里,我们可以列出我们想要显示的属性。

class ModelSerializer < ActiveModel::Serializer
  attributes :id, :attribute1, :attribute2, ...
end

对于许多情况,如果不是大多数情况,这就是您所需要的。考虑一下,您可以决定要显示的属性以及要排除哪些属性。但是,如果您只需要更多。借助我们的关联(HAS_MANY,属于属于)和自定义实例方法,我们可以利用序列化的全部功能。有点像与力量(如果您是星球大战的粉丝)或攻击速度力(如果您喜欢闪光灯)。

在我继续用自己的项目中的示例中进行说明时,请注意这一点。我将从序列化关联开始。让我们从我的Provider型号开始。

模式

  create_table "providers", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
    t.string "first_name"
    t.string "middle_name"
    t.string "last_name"
    t.string "type_of_provider"
    t.string "department"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

模型

class Provider < ApplicationRecord
    validates :username, :first_name, :last_name, :type_of_provider, :department, presence: true
    validates :username, uniqueness: true

    has_secure_password
    has_many :appointments
    has_many :patients, through: :appointments
end

序列化器

class ProviderSerializer < ActiveModel::Serializer
  attributes :id, :username, :first_name, :middle_name, :last_name, :type_of_provider, :department
  has_many :appointments
  has_many :patients
end

JSON输出

  {
    "id": 3,
    "username": "doctorstrange",
    "first_name": "Stephen",
    "middle_name": "Allen",
    "last_name": "Strange",
    "type_of_provider": "Physician",
    "department": "Neurosurgery",
    "patients": [
      {
        "id": 7,
        "first_name": "Cletus",
        "middle_name": "Ziemann",
        "last_name": "Altenwerth",
        "birth_date": "1961-02-19T00:00:00.000Z",
        "sex": "M",
        "image": "",
        "address": "778 Vance Summit Jewellton, Arkansas 05528-0096",
        "phone_number": "1-486-568-3938 x766",
        "email_address": "roberto@wolf.test",
        "insurance": "Aetna",
        "age": 62,
        "picture": null
      },
      {
        "id": 9,
        "first_name": "Kayce",
        "middle_name": "MacGyver",
        "last_name": "DuBuque",
        "birth_date": "1988-06-30T00:00:00.000Z",
        "sex": "F",
        "image": "",
        "address": "910 Ankunding Road East Jacquelynborough, Kentucky 95561",
        "phone_number": "(346) 455-8971 x90000",
        "email_address": "glendora@greenfelder.test",
        "insurance": "Cigna",
        "age": 34,
        "picture": null
      }
    ],
    "appointments": [
      {
        "id": 18,
        "provider_id": 3,
        "patient_id": 7,
        "type_of_appointment": "Inpatient: Surgery",
        "location": "NYU Langone Brain and Spine Center",
        "date": "2023-05-06T19:30:00.674Z"
      },
      {
        "id": 19,
        "provider_id": 3,
        "patient_id": 9,
        "type_of_appointment": "Outpatient: Consultation",
        "location": "NYU Brain and Spine Center",
        "date": "2023-05-06T19:12:48.112Z"
      }
    ]
  }

在上面的示例中,我采用了一个名为Provider的模型,并使用了一个名为ProviderSerializer的序列化器来自定义JSON输出,以显示Provider的属性,如序列化器的属性部分中所示,以及所有患者和医生的约会,使用此模型的已知关联很奇怪。

让我们注意一些事情。请注意,ProviderSerializerActiveModel::Serializer继承。此外,序列化器的名称遵循典型的导轨“对配置的约定”,因为名称是模型名称(单数!)和序列化器。请注意,包括password digestcreated_atupdated_at以外的所有属性都用于显示。使用has_many宏的使用允许显示与Strange博士有关的所有患者和约会。

让我们踢一个档次。与其返回有关患者的所有信息和此提供者的约会返回患者名单和仅提供基本信息的约会。我们可以在序列化器中使用自定义方法来执行此操作。

序列化器

class ProviderSerializer < ActiveModel::Serializer
  attributes :id, :username, :first_name, :middle_name, :last_name, :type_of_provider, :department, :patient_list, :appointment_list

  def patient_list
    patients=self.object.patients
    patients.map do |patient|
      "#{patient.last_name}, #{patient.first_name} DOB: #{patient.birth_date.strftime("%m/%d/%Y")}"      
    end
  end

  def appointment_list
    appointments=self.object.appointments
    appointments.map do |appointment|
      patient=Patient.find(appointment.patient_id)
      "#{patient.last_name}, #{patient.first_name} || Type of appointment: #{appointment.type_of_appointment} || Location: #{appointment.location } || Date: #{appointment.date.strftime("%m/%d/%Y")}" 
    end
  end
end

请注意,我创建了两种实例方法detter_list和timment_list,分别以缩写形式返回患者和约会的列表。另请注意,使用self.object来指代selfProvider实例)类似于您在Ruby中使用self的方式。这是我们下面的JSON输出。请注意,看起来好多了,如此甜美和如此光滑。

JSON输出

  {
    "id": 3,
    "username": "doctorstrange",
    "first_name": "Stephen",
    "middle_name": "Allen",
    "last_name": "Strange",
    "type_of_provider": "Physician",
    "department": "Neurosurgery",
    "patient_list": [
      "Altenwerth, Cletus DOB: 02/19/1961",
      "DuBuque, Kayce DOB: 06/30/1988"
    ],
    "appointment_list": [
      "Altenwerth, Cletus || Type of appointment: Inpatient: Surgery || Location: NYU Langone Brain and Spine Center || Date: 05/06/2023",
      "DuBuque, Kayce || Type of appointment: Outpatient: Consultation || Location: NYU Brain and Spine Center || Date: 05/06/2023"
    ]
  }

可以看到串行序列是我们的导轨工具箱中的另一个工具,我们可以用来增强应用程序的丰富性。在此示例中,完全从后端为Strange博士生成了简化的患者列表和约会清单,而前端没有工作。只要满足某些条件,就可以用任何资源来完成。可以使用关联和自定义方法将序列化提升到一个新的级别。这是序列化的力量。我出去了。