<commit_before># == Schema Information
#
# Table name: alerts
#
#  alert_type_id :bigint(8)
#  created_at    :datetime         not null
#  data          :json
#  id            :bigint(8)        not null, primary key
#  run_on        :date
#  school_id     :bigint(8)
#  status        :integer
#  summary       :text
#  updated_at    :datetime         not null
#
# Indexes
#
#  index_alerts_on_alert_type_id  (alert_type_id)
#  index_alerts_on_school_id      (school_id)
#

class Alert < ApplicationRecord
  belongs_to :school,     inverse_of: :alerts
  belongs_to :alert_type, inverse_of: :alerts

  delegate :title, to: :alert_type
  delegate :description, to: :alert_type
  delegate :display_fuel_type, to: :alert_type

  scope :electricity,         -> { joins(:alert_type).merge(AlertType.electricity) }
  scope :gas,                 -> { joins(:alert_type).merge(AlertType.gas) }
  scope :no_fuel,             -> { joins(:alert_type).merge(AlertType.no_fuel) }
  scope :termly,              -> { joins(:alert_type).merge(AlertType.termly) }
  scope :weekly,              -> { joins(:alert_type).merge(AlertType.weekly) }
  scope :before_each_holiday, -> { joins(:alert_type).merge(AlertType.before_each_holiday) }
  scope :usable,              -> { where(status: [:good, :poor])}

  enum status: [:good, :poor, :not_enough_data, :failed]

  def self.latest
    a = Alert.arel_table
    find_by_sql(a.project(a[Arel.star]).distinct_on(a[:alert_type_id]).order(a[:alert_type_id], 'created_at desc'))
  end

  # Data hash may end up being attributes of alert
  # Also uses string keys as serialised as JSON in DB
  def detail
    data['detail']
  end

  def help_url
    data['help_url']
  end

  def frequency
    alert_type.frequency
  end

  def show_ratings?
    alert_type.show_ratings<commit_msg>Use straight SQL rather than Arel<commit_after># == Schema Information
#
# Table name: alerts
#
#  alert_type_id :bigint(8)
#  created_at    :datetime         not null
#  data          :json
#  id            :bigint(8)        not null, primary key
#  run_on        :date
#  school_id     :bigint(8)
#  status        :integer
#  summary       :text
#  updated_at    :datetime         not null
#
# Indexes
#
#  index_alerts_on_alert_type_id  (alert_type_id)
#  index_alerts_on_school_id      (school_id)
#

class Alert < ApplicationRecord
  belongs_to :school,     inverse_of: :alerts
  belongs_to :alert_type, inverse_of: :alerts

  delegate :title, to: :alert_type
  delegate :description, to: :alert_type
  delegate :display_fuel_type, to: :alert_type

  scope :electricity,         -> { joins(:alert_type).merge(AlertType.electricity) }
  scope :gas,                 -> { joins(:alert_type).merge(AlertType.gas) }
  scope :no_fuel,             -> { joins(:alert_type).merge(AlertType.no_fuel) }
  scope :termly,              -> { joins(:alert_type).merge(AlertType.termly) }
  scope :weekly,              -> { joins(:alert_type).merge(AlertType.weekly) }
  scope :before_each_holiday, -> { joins(:alert_type).merge(AlertType.before_each_holiday) }
  scope :usable,              -> { where(status: [:good, :poor])}

  enum status: [:good, :poor, :not_enough_data, :failed]

  def self.latest
    select('DISTINCT ON ("alert_type_id") alerts.*').order('alert_type_id', created_at: :desc)
  end

  # Data hash may end up being attributes of alert
  # Also uses string keys as serialised as JSON in DB
  def detail
    data['detail']
  end

  def help_url
    data['help_url']
  end

  def frequency
    alert_type.frequency
  end

  def show_ratings?
    alert_type.show_ratings
{'fraction_non_alphanumeric': 0.11368715083798883, 'fraction_numerical': 0.0016759776536312849, 'mean_word_length': 2.9833147942157954, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6300732', 'n_tokens_mistral': 1248, 'n_tokens_neox': 1198, 'n_words': 267}