diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 32ccdcd5..ccbf139e 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -17,7 +17,7 @@ class Transaction < ApplicationRecord def sluggables = [recipe_no] # * Enums - enum :mode, MODES + enum mode: MODES # * Scopes scope :that_occured_on, ->(date) { where(date: date) } diff --git a/app/views/transactions/_form.html.erb b/app/views/transactions/_form.html.erb index 61f4e72a..c7901383 100644 --- a/app/views/transactions/_form.html.erb +++ b/app/views/transactions/_form.html.erb @@ -3,7 +3,11 @@ <%= f.error_notification %> <%= f.input :recipe_no %> <%= f.input :amount, hint: "Amount shouldn't be greater than: ₹#{total_balance}" %> - <%= f.input :mode, collection: MODES.map { [_1.capitalize, _1] }, as: :radio_buttons %> + <% if action_name == "edit" %> + <%= f.input :mode, collection: MODES.keys.map { [_1.capitalize, _1] }, as: :radio_buttons %> + <% else %> + <%= f.input :mode, input_html: {checked: false}, collection: MODES.keys.map { [_1.capitalize, _1] }, as: :radio_buttons %> + <% end %> <%= f.input :date, order: %i[day month year] %> <%= f.button :submit, action_name: %> <% end %> diff --git a/config/initializers/constant.rb b/config/initializers/constant.rb index 86a1f086..b52a912f 100644 --- a/config/initializers/constant.rb +++ b/config/initializers/constant.rb @@ -13,7 +13,12 @@ large: "Large" } -MODES = %i[cash cheque bank] +MODES = { + cash: "Cash", + cheque: "Cheque", + bank: "Bank" +} + ROLES = %w[admin member viewer] CURR_YR = 2022 PREV_YR = CURR_YR - 1 diff --git a/db/migrate/20231230171413_replace_mode_integer_with_mode_enum_type_in_transaction.rb b/db/migrate/20231230171413_replace_mode_integer_with_mode_enum_type_in_transaction.rb new file mode 100644 index 00000000..3bb13675 --- /dev/null +++ b/db/migrate/20231230171413_replace_mode_integer_with_mode_enum_type_in_transaction.rb @@ -0,0 +1,29 @@ +class ReplaceModeIntegerWithModeEnumTypeInTransaction < ActiveRecord::Migration[7.1] + def change + modes = %w[Cash Cheque Bank] + create_enum :modes, modes + + add_column :transactions, :mode_enum, :enum, enum_type: :modes, default: "Cash", null: false + + reversible do |direction| + # rubocop:disable Rails/SkipsModelValidations + direction.up do + modes.each_with_index do |mode, i| + Transaction.where(mode: i).update_all(mode_enum: mode) + end + end + + direction.down do + modes.each_with_index do |mode, i| + Transaction.where(mode_enum: mode).update_all(mode: i) + end + # make sure to update the MODES constant value in order to access the 'mode' data + # MODES = %i[cash cheque bank] + end + # rubocop:enable Rails/SkipsModelValidations + end + + remove_column :transactions, :mode, :integer + rename_column :transactions, :mode_enum, :mode + end +end diff --git a/db/schema.rb b/db/schema.rb index 1e8c37c5..fa6df687 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_30_135852) do +ActiveRecord::Schema[7.1].define(version: 2023_12_30_171413) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" # Custom types defined in this database. # Note that some types may not work with other database engines. Be careful if changing database. create_enum "apartments", ["Mohammedi", "Taiyebi", "Burhani", "Maimoon A", "Maimoon B"] + create_enum "modes", ["Cash", "Cheque", "Bank"] create_enum "sizes", ["Small", "Medium", "Large"] create_table "friendly_id_slugs", force: :cascade do |t| @@ -71,12 +72,12 @@ create_table "transactions", force: :cascade do |t| t.bigint "thaali_id", null: false t.integer "recipe_no", null: false - t.integer "mode", null: false t.integer "amount", null: false t.date "date", null: false t.string "slug", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.enum "mode", default: "Cash", null: false, enum_type: "modes" t.index ["recipe_no"], name: "index_transactions_on_recipe_no", unique: true t.index ["slug"], name: "index_transactions_on_slug", unique: true t.index ["thaali_id"], name: "index_transactions_on_thaali_id" diff --git a/db/seeds.rb b/db/seeds.rb index c1ddd195..92eb1e80 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -33,7 +33,7 @@ amount: 4000, date: Faker::Date.in_date_period(year: PREV_YR), recipe_no: Random.rand(1..2000000), - mode: MODES.sample + mode: MODES.keys.sample ) end end @@ -48,7 +48,7 @@ amount: 4000, date: Faker::Date.in_date_period(year: PREV_YR), recipe_no: Random.rand(2000001..3000000), - mode: MODES.sample + mode: MODES.keys.sample ) end end @@ -75,7 +75,7 @@ amount: 5000, date: Faker::Date.in_date_period(year: CURR_YR), recipe_no: Random.rand(3000001..6000000), - mode: MODES.sample + mode: MODES.keys.sample ) end end @@ -91,7 +91,7 @@ amount: 5000, date: Faker::Date.in_date_period(year: CURR_YR), recipe_no: Random.rand(6000000..10000000), - mode: MODES.sample + mode: MODES.keys.sample ) end end diff --git a/spec/factories/transactions.rb b/spec/factories/transactions.rb index d7582438..f55dc0dd 100644 --- a/spec/factories/transactions.rb +++ b/spec/factories/transactions.rb @@ -6,7 +6,7 @@ amount { Faker::Number.number(digits: 4) } date { Faker::Date.backward } recipe_no { Random.rand(1000..100000) } - sequence :mode, MODES.cycle + sequence :mode, MODES.keys.cycle factory :cleared_transaction, traits: [:cleared] factory :today_transaction, traits: [:today] diff --git a/spec/features/transactions/new_spec.rb b/spec/features/transactions/new_spec.rb index 52aefde3..e98be2dd 100644 --- a/spec/features/transactions/new_spec.rb +++ b/spec/features/transactions/new_spec.rb @@ -24,7 +24,7 @@ let(:new_transaction) { Transaction.last } before do - choose MODES.sample.capitalize + choose MODES.values.sample click_button "Create Transaction" end diff --git a/spec/models/transaction_spec.rb b/spec/models/transaction_spec.rb index 78b194e6..1fa11e54 100644 --- a/spec/models/transaction_spec.rb +++ b/spec/models/transaction_spec.rb @@ -13,10 +13,9 @@ context "when validating" do context "with mode" do - let(:mode_of_payments) { %i[cash cheque bank] } - it { is_expected.to validate_presence_of(:mode).with_message("selection is required") } - it { is_expected.to define_enum_for(:mode).with_values(mode_of_payments) } + + it { is_expected.to define_enum_for(:mode).with_values(MODES).backed_by_column_of_type(:enum) } end context "with amount" do