QutBioacoustics/baw-server

View on GitHub
app/models/response.rb

Summary

Maintainability
A
3 hrs
Test Coverage
# frozen_string_literal: true

# == Schema Information
#
# Table name: responses
#
#  id              :integer          not null, primary key
#  data            :text
#  created_at      :datetime
#  creator_id      :integer
#  dataset_item_id :integer
#  question_id     :integer
#  study_id        :integer
#
# Foreign Keys
#
#  fk_rails_...  (creator_id => users.id)
#  fk_rails_...  (dataset_item_id => dataset_items.id)
#  fk_rails_...  (question_id => questions.id)
#  fk_rails_...  (study_id => studies.id)
#
class Response < ApplicationRecord
  # relationships
  belongs_to :creator, class_name: 'User', foreign_key: :creator_id, inverse_of: :created_responses
  belongs_to :question
  belongs_to :study
  belongs_to :dataset_item

  # association validations
  validates :creator, presence: true
  validates :question, presence: true
  validates :study, presence: true
  validates :dataset_item, presence: true
  validates :data, presence: true

  # Response is associated with study directly and also via question
  # validate that the associated study and question are associated with each other

  validate :consistent_associations

  # Define filter api settings
  def self.filter_settings
    {
      valid_fields: [:id, :data, :created_at, :creator_id, :study_id, :question_id, :dataset_item_id],
      render_fields: [:id, :data, :created_at, :creator_id, :study_id, :question_id, :dataset_item_id],
      new_spec_fields: lambda { |_user|
                         {
                           data: nil
                         }
                       },
      controller: :responses,
      action: :filter,
      defaults: {
        order_by: :created_at,
        direction: :desc
      },
      valid_associations: [
        {
          join: Question,
          on: Question.arel_table[:id].eq(Response.arel_table[:question_id]),
          available: true
        },
        {
          join: Study,
          on: Study.arel_table[:id].eq(Response.arel_table[:study_id]),
          available: true
        },
        {
          join: DatasetItem,
          on: DatasetItem.arel_table[:id].eq(Response.arel_table[:dataset_item_id]),
          available: true
        }
      ]
    }
  end

  private

  def consistent_associations
    if !study.nil? && !question.nil?
      unless study.question_ids.include?(question.id)
        errors.add(:question_id, 'parent question is not associated with parent study')
      end
    end
    if !study.nil? && !dataset_item.nil?
      if study.dataset_id != dataset_item.dataset_id
        errors.add(:dataset_item_id, 'dataset item and study must belong to the same dataset')
      end
    end
  end
end