Account:: namespace simplifications and cleanup #2110

Merged
zachgoll merged 9 commits from zachgoll/entryable-namespace-simplifications into main 2025-04-14 23:40:34 +08:00
zachgoll commented 2025-04-14 22:06:46 +08:00 (Migrated from github.com)

This PR clarifies the Account domain by removing the namespace from the Balance, Holding, and Entry model. These models are first-class domain concepts that have been tucked beneath the Account:: namespace; obscuring their usage throughout routes, controllers, and views.

With these changes, everything is now a "flat" model; only utilizing namespaces as an organizational tool for non-ActiveRecord models rather than nesting the ActiveRecord models themselves under a namespace.

Summary of changes

Naming simplifications

From this:

# classes
Account::Entry
Account::Transaction
Account::Trade
Account::Valuation
Account::Balance
Account::Balance::BaseCalculator
Account::Holding
Account::Holding::BaseCalculator

# Access
account.account_entries.account_transactions
account.account_entries.account_trades
account.account_valuations.account_valuations

To this:

# classes
Entry
Transaction
Trade
Valuation
Balance
Balance::BaseCalculator
Holding
Holding::BaseCalculator

# Access
account.entries.transactions
account.entries.trades
account.entries.valuations

Bulk controllers

Previously all bulk operations were happening in transactions_controller, now split to dedicated controllers:

namespace :transactions do
  resource :bulk_deletion, only: :create
  resource :bulk_update, only: %i[new create]
end

class Transactions::BulkUpdatesController < ApplicationController
  def new
  end

  def create
  end
end

class Transactions::BulkDeletionsController < ApplicationController
  def create
  end
end

Simplification of entryable_resource module

EntryableResource now delegates both update and create to the Entryable controller, simplifying params:

module EntryableResource
  extend ActiveSupport::Concern

  included do
    include StreamExtensions, ActionView::RecordIdentifier

    before_action :set_entry, only: %i[show update destroy]
  end

  def show
  end

  def new
    account = Current.family.accounts.find_by(id: params[:account_id])

    @entry = Current.family.entries.new(
      account: account,
      currency: account ? account.currency : Current.family.currency,
      entryable: entryable
    )
  end

  def create
    raise NotImplementedError, "Entryable resources must implement #create"
  end

  def update
    raise NotImplementedError, "Entryable resources must implement #update"
  end

  def destroy
    account = @entry.account
    @entry.destroy!
    @entry.sync_account_later

    redirect_back_or_to account_path(account), notice: t("account.entries.destroy.success")
  end

  private
    def entryable
      controller_name.classify.constantize.new
    end

    def set_entry
      @entry = Current.family.entries.find(params[:id])
    end
end

This PR clarifies the Account domain by removing the namespace from the `Balance`, `Holding`, and `Entry` model. These models are first-class domain concepts that have been tucked beneath the `Account::` namespace; obscuring their usage throughout routes, controllers, and views. With these changes, everything is now a "flat" model; only utilizing namespaces as an _organizational_ tool for non-ActiveRecord models rather than nesting the ActiveRecord models themselves under a namespace. ## Summary of changes **Naming simplifications** From this: ```rb # classes Account::Entry Account::Transaction Account::Trade Account::Valuation Account::Balance Account::Balance::BaseCalculator Account::Holding Account::Holding::BaseCalculator # Access account.account_entries.account_transactions account.account_entries.account_trades account.account_valuations.account_valuations ``` To this: ```rb # classes Entry Transaction Trade Valuation Balance Balance::BaseCalculator Holding Holding::BaseCalculator # Access account.entries.transactions account.entries.trades account.entries.valuations ``` **Bulk controllers** Previously all bulk operations were happening in `transactions_controller`, now split to dedicated controllers: ```rb namespace :transactions do resource :bulk_deletion, only: :create resource :bulk_update, only: %i[new create] end class Transactions::BulkUpdatesController < ApplicationController def new end def create end end class Transactions::BulkDeletionsController < ApplicationController def create end end ``` **Simplification of `entryable_resource` module** EntryableResource now delegates both `update` and `create` to the Entryable controller, simplifying params: ```rb module EntryableResource extend ActiveSupport::Concern included do include StreamExtensions, ActionView::RecordIdentifier before_action :set_entry, only: %i[show update destroy] end def show end def new account = Current.family.accounts.find_by(id: params[:account_id]) @entry = Current.family.entries.new( account: account, currency: account ? account.currency : Current.family.currency, entryable: entryable ) end def create raise NotImplementedError, "Entryable resources must implement #create" end def update raise NotImplementedError, "Entryable resources must implement #update" end def destroy account = @entry.account @entry.destroy! @entry.sync_account_later redirect_back_or_to account_path(account), notice: t("account.entries.destroy.success") end private def entryable controller_name.classify.constantize.new end def set_entry @entry = Current.family.entries.find(params[:id]) end end ```
Sign in to join this conversation.