DEV Community

K Putra
K Putra

Posted on

Validasi Uniqueness Attribute antar Model dalam Rails

Beberapa waktu yang lalu saya menemui situasi di mana saya harus melakukan validasi uniqueness di antara dua model. Saya memiliki dua model yang sama-sama memiliki atribut phone_number dan dalam satu sistem yang saya bangun atribut ini harus unique.

Jika model A sudah memiliki phone_number 0811213305, maka model B juga tidak boleh memiliki phone_number dengan nomor yang sama.

Ruby on Rails memberikan kemudahan untuk melakukan unique validation dalam satu model dengan cara yang sangat mudah, namun tidak untuk unique validation dalam dua atau lebih model. Berarti, saya harus membuat sendiri validasi ini.

Setelah melakukan riset, maka saya pun menemukan algoritma yang menurut saya cukup simpel dan mudah untuk direproduksi sesuai kebutuhan.

Berikut adalah code saya:

# app/models/concerns/validate_phone_number.rb
module ValidatePhoneNumber
    extend ActiveSupport::Concern

    @@included_classes = []

    included do
        @@included_classes << self
        validate :phone_number_in_all_model
    end

    private

    def phone_number_in_all_model
        return if self.phone_number.blank?
        @@included_classes.each do |klass|
            scope = klass.where(phone_number: self.phone_number)
            if self.persisted? && klass == self.class
                scope = scope.where('id != ?', self.id)
            end
            if scope.any?
                self.errors.add :phone_number, 'is already taken.'
                break
            end
        end
    end
end
Enter fullscreen mode Exit fullscreen mode

Jangan lupa untuk include Module di dalam masing-masing model yang hendak divalidasi.

# app/models/customer.rb
class Customer < ApplicationRecord
    include ValidatePhoneNumber
end


# app/models/branch.rb
class Branch < ApplicationRecord
    include ValidatePhoneNumber
end
Enter fullscreen mode Exit fullscreen mode

Setelah memasukkan code ini, voila, maka atribut phone_number akan dipaksa untuk unique di kedua model, yaitu model Customer dan model Branch.

Kelemahan dari code ini adalah masih memungkinkannya terjadi duplikasi atribut ketika race condition.

Semoga artikel ini bisa membantu yang sedang kesulitan.

Note:

  • Code ini saya temukan di suatu artikel yang saya tidak bisa temukan lagi karena lupa kata kunci search google;
  • Copas dari artikel saya

Top comments (2)

Collapse
 
eusebiusmarcel profile image
Eusebius Marcel

Tes

Collapse
 
eusebiusmarcel profile image
Eusebius Marcel

Tes lagi