kabisa / launch-base

MIT License
1 stars 0 forks source link

Standard Ruby ActiveRecord model structure #66

Open flarik opened 5 years ago

flarik commented 5 years ago

It would be nice if we had an standard ActiveRecord model structure, so every model looks familiar and structured.

Proposal:

class XY < ApplicationRecord
  # --- Constants ----------------------------------------------------------->>
  # --- Constants ----------------------------------------------------------->>

  # --- Class eval ----------------------------------------------------------->>
  # --- Class eval ----------------------------------------------------------->>

  # --- Concerns ------------------------------------------------------------->>
  # --- Concerns ------------------------------------------------------------->>

  # --- Attributes ----------------------------------------------------------->>
  # --- Attributes ----------------------------------------------------------->>

  # --- Relations ------------------------------------------------------------>>
  # --- Relations ------------------------------------------------------------>>

  # --- Nested attributes ---------------------------------------------------->>
  # --- Nested attributes ---------------------------------------------------->>

  # --- Validations ---------------------------------------------------------->>
  # --- Validations ---------------------------------------------------------->>

  # --- Callbacks ------------------------------------------------------------>>
  # --- Callbacks ------------------------------------------------------------>>

  # --- Scopes --------------------------------------------------------------->>
  # --- Scopes --------------------------------------------------------------->>
end

Real life example:

class License < ApplicationRecord
  # --- Constants ------------------------------------------------------------>>
  AMOUNT_MINIMUM = 0
  AMOUNT_MAXIMUM = 10_000
  # --- Constants ------------------------------------------------------------>>

  # --- Class eval ----------------------------------------------------------->>
  # --- Class eval ----------------------------------------------------------->>

  # --- Concerns ------------------------------------------------------------->>
  # --- Concerns ------------------------------------------------------------->>

  # --- Attributes ----------------------------------------------------------->>
  delegate :name, to: :definition
  delegate :countable?, to: :definition
  # --- Attributes ----------------------------------------------------------->>

  # --- Relations ------------------------------------------------------------>>
  belongs_to :organisation
  belongs_to :definition,
             class_name: 'LicenseDefinition',
             foreign_key: 'license_definition_id'
  has_many :license_connections,
           through: :definition
  has_many :route_matchers,
           through: :license_connections
  has_many :mutations,
           -> { order('created_at desc') },
           class_name: 'LicenseMutation'
  has_many :schedules,
           class_name: 'LicenseSchedule'
  # --- Relations ------------------------------------------------------------>>

  # --- Nested attributes ---------------------------------------------------->>
  # --- Nested attributes ---------------------------------------------------->>

  # --- Validations ---------------------------------------------------------->>
  validates :organisation_id,
            presence: true,
            format: { with: Organisation::UUID_REGEXP }

  validates :license_definition_id,
            numericality: {
              only_integer: true,
              greater_than: 0
            },
            uniqueness: {
              scope: :organisation_id,
              on: :create
            }

  validates :amount,
            numericality: {
              only_integer: true,
              greater_than_or_equal_to: AMOUNT_MINIMUM,
              less_than_or_equal_to: AMOUNT_MAXIMUM
            }

  validates :enabled, inclusion: [true, false]
  # --- Validations ---------------------------------------------------------->>

  # --- Callbacks ------------------------------------------------------------>>
  before_save :set_amount_unless_countable
  after_save :mutate!
  # --- Callbacks ------------------------------------------------------------>>

  # --- Scopes --------------------------------------------------------------->>
  scope :organisation, (lambda do |organisation_id|
    where(organisation_id: organisation_id)
  end)
  scope :counting_method,
        (lambda do |counting_method|
          joins(:definition)
            .where('license_definitions.counting_method' => counting_method)
        end)
  scope :role,
        (lambda do |role|
          joins(:definition)
            .where('license_definitions.role' => role)
        end)
  scope :enabled, -> { where(enabled: true) }
  # --- Scopes --------------------------------------------------------------->>
end