QutBioacoustics/baw-server

View on GitHub
app/models/dataset.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

# == Schema Information
#
# Table name: datasets
#
#  id          :integer          not null, primary key
#  description :text
#  name        :string
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#  creator_id  :integer
#  updater_id  :integer
#
# Foreign Keys
#
#  fk_rails_...  (creator_id => users.id)
#  fk_rails_...  (updater_id => users.id)
#
class Dataset < ApplicationRecord
  #relationships
  belongs_to :creator, class_name: 'User', foreign_key: :creator_id, inverse_of: :created_datasets
  belongs_to :updater, class_name: 'User', foreign_key: :updater_id, inverse_of: :updated_datasets, optional: true
  has_many :dataset_items, dependent: :destroy
  has_many :study

  # We have not enabled soft deletes yet since we do not support deleting datasets
  # This may change in the future

  # association validations
  #validates_associated :creator

  # validation
  validates :name, presence: true, length: { minimum: 2 }
  validates :name, unless: -> { id == Dataset.default_dataset_id }, exclusion: { in: ['default'], message: '%{value} is a reserved dataset name' }

  DEFAULT_DATASET_NAME = 'default'

  # lookup the default dataset id
  # This will potentially be hit very often, maybe multiple times per request
  # and therefore is a possible avenue for future optimization if necessary
  def self.default_dataset_id
    # note: this may cause db:create and db:migrate to fail
    default_dataset.id
  end

  # (scope) return the default dataset
  def self.default_dataset
    Dataset.where(name: DEFAULT_DATASET_NAME).first
  end

  # Define filter api settings
  def self.filter_settings
    {
      valid_fields: [
        :id, :name, :description, :created_at, :creator_id, :updated_at, :updater_id
      ],
      render_fields: [
        :id, :name, :description, :created_at, :creator_id, :updated_at, :updater_id
      ],
      custom_fields: lambda { |item, _user|
        [item, item.render_markdown_for_api_for(:description)]
      },
      new_spec_fields: lambda { |_user|
                         {
                           name: nil,
                           description: nil
                         }
                       },
      controller: :datasets,
      action: :filter,
      defaults: {
        order_by: :name,
        direction: :asc
      },
      valid_associations: [
        {
          join: DatasetItem,
          on: Dataset.arel_table[:id].eq(DatasetItem.arel_table[:dataset_id]),
          available: true,
          associations: [
            {
              join: ProgressEvent,
              on: DatasetItem.arel_table[:id].eq(ProgressEvent.arel_table[:dataset_item_id]),
              available: true,
              associations: []

            },
            {
              join: AudioRecording,
              on: DatasetItem.arel_table[:audio_recording_id].eq(AudioRecording.arel_table[:id]),
              available: true,
              associations: []

            }
          ]
        }
      ]
    }
  end

  def self.schema
    {
      type: 'object',
      additionalProperties: false,
      properties: {
        id: { '$ref' => '#/components/schemas/id', readOnly: true },
        name: { type: 'string' },
        **Api::Schema.rendered_markdown(:description),
        **Api::Schema.updater_and_creator_user_stamps
      },
      required: [
        :id,
        :name,
        :description,
        :created_at,
        :creator_id,
        :updated_at,
        :updater_id
      ]
    }.freeze
  end
end