diff --git a/app/models/concerns/nameable.rb b/app/models/concerns/nameable.rb index 8e54efd..5775859 100644 --- a/app/models/concerns/nameable.rb +++ b/app/models/concerns/nameable.rb @@ -6,16 +6,17 @@ module Nameable included do pg_enum :sex, %i[male female] - before_validation :turn_blank_middle_name_into_nil + before_validation :turn_blank_nameable_attributes_into_nils + validates :last_name, presence: true validates :first_name, presence: true - validates :last_name, presence: true - validates :sex, presence: true - validates :date_of_birth, presence: true - validates :place_of_birth, presence: true end - def turn_blank_middle_name_into_nil - self.middle_name = nil if middle_name.blank? + def turn_blank_nameable_attributes_into_nils + %i[ + last_name first_name middle_name sex date_of_birth place_of_birth + ].each do |attribute| + public_send "#{attribute}=", nil if public_send(attribute).blank? + end end end diff --git a/app/models/concerns/required_nameable.rb b/app/models/concerns/required_nameable.rb new file mode 100644 index 0000000..fc84a26 --- /dev/null +++ b/app/models/concerns/required_nameable.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module RequiredNameable + extend ActiveSupport::Concern + + include Nameable + + included do + validates :sex, presence: true + validates :date_of_birth, presence: true + validates :place_of_birth, presence: true + end +end diff --git a/app/models/passport.rb b/app/models/passport.rb index e8556af..a872d83 100644 --- a/app/models/passport.rb +++ b/app/models/passport.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Passport < ApplicationRecord - include Nameable + include RequiredNameable FORMAT_RE = /\A[^[:space:]]+(.*[^[:space:]]+)?\z/.freeze diff --git a/app/views/staffs/people/index.html.erb b/app/views/staffs/people/index.html.erb index 70bde6a..cee8567 100644 --- a/app/views/staffs/people/index.html.erb +++ b/app/views/staffs/people/index.html.erb @@ -32,10 +32,12 @@ <%= truncate person.middle_name, length: 15 %> <%= truncate person.last_name, length: 15 %> - <%= localize person.date_of_birth %> + <%= localize person.date_of_birth if person.date_of_birth %> - <%= truncate person.place_of_birth, length: 15 %> + <% if person.place_of_birth %> + <%= truncate person.place_of_birth, length: 15 %> + <% end %> <% if policy([:staff, person]).show? %> diff --git a/app/views/staffs/people/show.html.erb b/app/views/staffs/people/show.html.erb index 7137f1b..0240380 100644 --- a/app/views/staffs/people/show.html.erb +++ b/app/views/staffs/people/show.html.erb @@ -12,13 +12,13 @@
<%= truncate @person.last_name %>
<%= Person.human_attribute_name :sex %>
-
<%= translate_enum :sex, @person.sex %>
+
<%= translate_enum :sex, @person.sex if @person.sex %>
<%= Person.human_attribute_name :date_of_birth %>
-
<%= localize @person.date_of_birth %>
+
<%= localize @person.date_of_birth if @person.date_of_birth %>
<%= Person.human_attribute_name :place_of_birth %>
-
<%= truncate @person.place_of_birth %>
+
<%= truncate @person.place_of_birth if @person.place_of_birth %>
<%= Person.human_attribute_name :current_regional_office %>
diff --git a/db/migrate/20181129203927_initial_migration.rb b/db/migrate/20181129203927_initial_migration.rb index 9254262..ddcaf21 100644 --- a/db/migrate/20181129203927_initial_migration.rb +++ b/db/migrate/20181129203927_initial_migration.rb @@ -102,9 +102,9 @@ class InitialMigration < ActiveRecord::Migration[6.0] t.string :first_name, null: false t.string :middle_name, null: true t.string :last_name, null: false - t.column :sex, :sex, null: false - t.date :date_of_birth, null: false - t.string :place_of_birth, null: false + t.column :sex, :sex, null: true + t.date :date_of_birth, null: true + t.string :place_of_birth, null: true t.references :contacts_list, null: false, index: { unique: true }, foreign_key: true diff --git a/db/structure.sql b/db/structure.sql index 65f9247..000da81 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -459,9 +459,9 @@ CREATE TABLE public.people ( first_name character varying NOT NULL, middle_name character varying, last_name character varying NOT NULL, - sex public.sex NOT NULL, - date_of_birth date NOT NULL, - place_of_birth character varying NOT NULL, + sex public.sex, + date_of_birth date, + place_of_birth character varying, contacts_list_id bigint NOT NULL ); diff --git a/spec/models/passport_spec.rb b/spec/models/passport_spec.rb index 34a5fb3..7a56602 100644 --- a/spec/models/passport_spec.rb +++ b/spec/models/passport_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' RSpec.describe Passport do subject { create :empty_passport } - it_behaves_like 'nameable' + it_behaves_like 'required_nameable' describe '#person' do it { is_expected.to belong_to(:person).optional } diff --git a/spec/models/shared_examples/nameable.rb b/spec/models/shared_examples/nameable.rb index cc721ec..e60c0aa 100644 --- a/spec/models/shared_examples/nameable.rb +++ b/spec/models/shared_examples/nameable.rb @@ -1,27 +1,40 @@ # frozen_string_literal: true RSpec.shared_examples 'nameable' do - it { is_expected.to validate_presence_of :first_name } + it { is_expected.to validate_presence_of :last_name } + it { is_expected.to validate_presence_of :first_name } it { is_expected.not_to validate_presence_of :middle_name } - it { is_expected.to validate_presence_of :last_name } - it { is_expected.to validate_presence_of :sex } - it { is_expected.to validate_presence_of :date_of_birth } - it { is_expected.to validate_presence_of :place_of_birth } + it { is_expected.not_to validate_presence_of :sex } + it { is_expected.not_to validate_presence_of :date_of_birth } + it { is_expected.not_to validate_presence_of :place_of_birth } - describe '#middle_name' do - context 'when it is empty' do - subject { create :member_person, middle_name: '' } + %i[ + last_name + first_name + middle_name + sex + date_of_birth + place_of_birth + ].each do |attribute| + describe "##{attribute}" do + context 'when it is empty' do + subject { build :member_person, attribute => '' } - specify do - expect(subject.middle_name).to eq nil + before { subject.validate } + + specify do + expect(subject.public_send(attribute)).to eq nil + end end - end - context 'when it is blank' do - subject { create :member_person, middle_name: ' ' } + context 'when it is blank' do + subject { build :member_person, attribute => ' ' } - specify do - expect(subject.middle_name).to eq nil + before { subject.validate } + + specify do + expect(subject.public_send(attribute)).to eq nil + end end end end diff --git a/spec/models/shared_examples/required_nameable.rb b/spec/models/shared_examples/required_nameable.rb new file mode 100644 index 0000000..308a20a --- /dev/null +++ b/spec/models/shared_examples/required_nameable.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'required_nameable' do + it { is_expected.to validate_presence_of :last_name } + it { is_expected.to validate_presence_of :first_name } + it { is_expected.not_to validate_presence_of :middle_name } + it { is_expected.to validate_presence_of :sex } + it { is_expected.to validate_presence_of :date_of_birth } + it { is_expected.to validate_presence_of :place_of_birth } + + %i[ + last_name + first_name + middle_name + sex + date_of_birth + place_of_birth + ].each do |attribute| + describe "##{attribute}" do + context 'when it is empty' do + subject { build :member_person, attribute => '' } + + before { subject.validate } + + specify do + expect(subject.public_send(attribute)).to eq nil + end + end + + context 'when it is blank' do + subject { build :member_person, attribute => ' ' } + + before { subject.validate } + + specify do + expect(subject.public_send(attribute)).to eq nil + end + end + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 532c433..1ada015 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -38,6 +38,7 @@ require_relative 'support/devise' require_relative 'support/pundit' require_relative 'models/shared_examples/nameable' +require_relative 'models/shared_examples/required_nameable' # Checks for pending migrations and applies them before tests are run. # If you are not using ActiveRecord, you can remove these lines.