From 428ce8eac421083c5b83aaddea829c62ef2120eb Mon Sep 17 00:00:00 2001 From: Denis Talakevich Date: Sun, 17 Nov 2019 14:49:04 +0200 Subject: [PATCH] add string presence type for optional unique columns --- app/models/employee.rb | 3 +++ app/models/student.rb | 4 ++++ config/initializers/active_record.rb | 1 + lib/custom_types/string_presence_type.rb | 10 ++++++++++ spec/models/employee_spec.rb | 14 ++++++++++++++ spec/models/student_spec.rb | 19 +++++++++++++++++++ 6 files changed, 51 insertions(+) create mode 100644 config/initializers/active_record.rb create mode 100644 lib/custom_types/string_presence_type.rb diff --git a/app/models/employee.rb b/app/models/employee.rb index a94b1af..b64abe6 100644 --- a/app/models/employee.rb +++ b/app/models/employee.rb @@ -22,6 +22,9 @@ class Employee < ApplicationRecord include ActsAsLoginable + attribute :inn, :string_presence + attribute :passport_number, :string_presence + validates :first_name, :last_name, presence: true validates :inn, :passport_number, uniqueness: true, allow_blank: true diff --git a/app/models/student.rb b/app/models/student.rb index cf27321..2bbb211 100644 --- a/app/models/student.rb +++ b/app/models/student.rb @@ -24,6 +24,10 @@ class Student < ApplicationRecord include ActsAsLoginable + attribute :inn, :string_presence + attribute :passport_number, :string_presence + attribute :ticket_number, :string_presence + validates :first_name, :last_name, presence: true validates :inn, :passport_number, :ticket_number, uniqueness: true, allow_blank: true diff --git a/config/initializers/active_record.rb b/config/initializers/active_record.rb new file mode 100644 index 0000000..ff62ce7 --- /dev/null +++ b/config/initializers/active_record.rb @@ -0,0 +1 @@ +require 'custom_types/string_presence_type' diff --git a/lib/custom_types/string_presence_type.rb b/lib/custom_types/string_presence_type.rb new file mode 100644 index 0000000..49ba1b4 --- /dev/null +++ b/lib/custom_types/string_presence_type.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class StringPresenceType < ActiveRecord::Type::String + def cast_value(value) + value = value.presence if value.is_a?(String) + super(value) + end +end + +ActiveRecord::Type.register :string_presence, StringPresenceType diff --git a/spec/models/employee_spec.rb b/spec/models/employee_spec.rb index bf69730..13794fc 100644 --- a/spec/models/employee_spec.rb +++ b/spec/models/employee_spec.rb @@ -56,6 +56,20 @@ include_examples :changes_records_count_of, described_class, by: 1 include_examples :changes_records_count_of, LoginRecord, by: 1 + context 'with inn and passport_number as empty strings' do + let(:create_params) do + super().merge inn: '', passport_number: '' + end + + include_examples :creates_record do + let(:expected_record_attrs) do + create_params.except(:login_record).merge(inn: nil, passport_number: '', allowed_services: match_array([1, 2])) + end + end + include_examples :changes_records_count_of, described_class, by: 1 + include_examples :changes_records_count_of, LoginRecord, by: 1 + end + context 'with optional attributes' do let(:create_params) do super().merge middle_name: 'Jamesovich', diff --git a/spec/models/student_spec.rb b/spec/models/student_spec.rb index 16df139..b901ad4 100644 --- a/spec/models/student_spec.rb +++ b/spec/models/student_spec.rb @@ -56,6 +56,25 @@ include_examples :changes_records_count_of, described_class, by: 1 include_examples :changes_records_count_of, LoginRecord, by: 1 + context 'with inn, ticket_number and passport_number as empty strings' do + let(:create_params) do + super().merge inn: '', passport_number: '', ticket_number: '' + end + + include_examples :creates_record do + let(:expected_record_attrs) do + create_params.except(:login_record).merge( + inn: nil, + passport_number: '', + ticket_number: '', + allowed_services: match_array([1, 2]) + ) + end + end + include_examples :changes_records_count_of, described_class, by: 1 + include_examples :changes_records_count_of, LoginRecord, by: 1 + end + context 'with optional attributes' do let(:create_params) do super().merge middle_name: 'Jamesovich',