بسم الله الرحمن الرحيم

Pendahuluan

Pada catatan kali ini saya ingin memodifikasi output dari nama attribute yang terlalu panjang menjadi lebih pendek di Ruby on Rails.

Masalah

Saya memiliki method geofences yang mengembalikan colllection of hash data dari model geofeonce.

Model geofence memiliki attributes,

:id, :created_at, :updated_at, :name, :description, :coordinates, :incoming_notification, :outgoing_notification

Saya hanya ingin mengambil attributes: :id, :incoming_notification, :outgoing_notification.

FILEapp/geofences_controller.rb
1
2
3
4
5
def geofences
  {
    geofences: Geofence.all.order(id: :asc).as_json(only: [:id, :incoming_notification, :outgoing_notification])
  }
end

Outputnya,

{
    "geofences": [
        {
            "id": 1,
            "incoming_notification": true,
            "outgoing_notification": false
        },
        {
            "id": 2,
            "incoming_notification": false,
            "outgoing_notification": true
        },
        {
            "id": 3,
            "incoming_notification": true,
            "outgoing_notification": false
        },
        {
            "id": 4,
            "incoming_notification": false,
            "outgoing_notification": true
        }
    ]
}

Karena nama attribute :incoming_notification dan :outgoing_notification terlalu panjang, saya akan ganti menjadi :in dan :out. 1

Pemecahan Masalah

Algoritma Pertama

FILEapp/geofences_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
# First algorithm
def geofences
  {
    geofences: Geofence.all.order(id: :asc)
      .as_json(only: [:id, :incoming_notification, :outgoing_notification])
      .each { |attribute|
        attribute.tap { |key|
          key[:in] = key.delete('incoming_notification')
          key[:out] = key.delete('outgoing_notification')
        }
      }
  }
end

Algoritma Kedua

FILEapp/geofences_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Second algorithm
def geofences
  geofences = Geofence.all.order(id: :asc)

  transformed_geofences = geofences.map do |geofence|
    {
      id: geofence.id,
      in: geofence.incoming_notification,
      out: geofence.outgoing_notification
    }
  end

  { geofences: transformed_geofences }
end

Saya menulis 2 pendekatan. Namun, saya cenderung memilih algoritma kedua.

Alasannya adalah,

Database Query Optimization:

  1. algoritma pertama, diambil semua data, lalu dilakukan filtering dan tranformation dengan .as_json
  2. algoritman kedua, hanya mengambil attribute yang diperlukan :id, :incoming_notification, :outgoing_notification dengan .map(), hal ini berpotensi untuk meminimalisir query time ke database

Reduced Object Mutation:

  1. algoritman pertama, menggunakan .each dengan .tap untuk memodifikasi Hash Object, hal ini terkadang dapat menyebabkan behaviour yang tidak dapat diprediksi sehingga menimbulkan bug.
  2. algoritma kedua, langsung membuat Hash Object dengan attribute yang diperlukan tanpa meodifikasi data aslinya, tentu saja ini menjadi pendekatan yang cukup aman

Hasilnya,

{
    "geofences": [
        {
            "id": 1,
            "in": true,
            "out": false
        },
        {
            "id": 2,
            "in": false,
            "out": true
        },
        {
            "id": 3,
            "in": true,
            "out": false
        },
        {
            "id": 4,
            "in": false,
            "out": true
        }
    ]
}

Pesan Penulis

Terima kasih sudah mampir yaa.

Referensi


Penulis

bandithijo

BanditHijo adalah nama pena saya –meminjam istilah keren dari para penulis. Teman-teman menyebut saya sebagai Linux Enthusiast. Saya memang gemar mengutak-atik sistem operasi ini. Sistem operasi ini memberikan saya kebebasan untuk mengekspresikan ide-ide dalam membantu menyelesaikan pekerjaan saya sehari-hari.

- Rizqi Nur Assyaufi

671cd596a74e62ed82281f84115576df8186aa14