SpeciesFileGroup/taxonworks

View on GitHub
app/models/language.rb

Summary

Maintainability
A
0 mins
Test Coverage
# This is a 1:1 representation of ISO 639-2.
# It is built on initialization with a rake task, and not further touched.
# Many of the languages have multiple version (e.g. there are 4 variations of German)
#
# @!attribute alpha_3_bibiographic
#   @return [String] attribute alpha_3_bibliographic always has a distinct 3 character value
#
# @!attribute alpha_3_terminologic
#   @return [String]
#
# @!attribute alpha_2
#   @return [String] alpha_2 will have either a 2 character value or and empty string ('')
#
# @!attribute english_name
#   @return [String] english_name may be more than one word long
#     (e.g. 'English, Middle (1100-1500)', 'Filipino; Pilipino','Finno-Ugrian languages')
#
# @!attribute french_name
#   @return [String] french_name may be more than one word long
#
class Language < ApplicationRecord
  include Housekeeping::Users
  include Housekeeping::Timestamps
  include Shared::IsData
  include Shared::IsApplicationData

  has_many :serials, inverse_of: :language, foreign_key: :primary_language_id
  has_many :sources, inverse_of: :source_language, class_name: 'Source::Bibtex'
  has_many :alternate_value_translations, class_name: 'AlternateValue::Translation'

  has_many :common_names, inverse_of: :language

  scope :used_recently_on_sources, -> { joins(sources: [:project_sources]).includes(sources: [:project_sources]).where(sources: { updated_at: 10.weeks.ago..Time.now } ).order('"sources"."updated_at" DESC') }


  # TODO: dry
  scope :used_recently_on_serials, -> { joins(:serials).includes(:serials).where(serials: { updated_at: 10.weeks.ago..Time.now } ).order('"serials"."updated_at" DESC') }
  scope :used_recently_on_common_names, -> { joins(:common_names).includes(:common_names).where(common_names: { updated_at: 10.weeks.ago..Time.now } ).order('"serials"."updated_at" DESC') }
  scope :used_recently_on_alternate_values, -> { joins(:alternate_value_translations).includes(:alternate_value_translations).where(alternate_values: { updated_at: 10.weeks.ago..Time.now } ).order('"alternate_values"."updated_at" DESC') }

  scope :with_english_name_containing, ->(name) {where('english_name ILIKE ?', "%#{name}%")}  # non-case sensitive comparison

  validates_presence_of :english_name, :alpha_3_bibliographic

  def self.with_english_name_or_abbreviation(value)
    value = [value] if value.class == String

    t = Language.arel_table
    a = t[:english_name].matches_any(value)
    b = t[:alpha_2].matches_any(value)
    c = t[:alpha_3_bibliographic].matches_any(value)
    d = t[:alpha_3_terminologic].matches_any(value)
    Language.where(a.or(b).or(c).or(d).to_sql)
  end

  def self.find_for_autocomplete(params)
    where('english_name ILIKE ? OR english_name = ?', "#{params[:term]}%", params[:term])
  end

  # @param klass ['Source' || 'Serial']
  def self.select_optimized(user_id, project_id, klass = 'Source')
    language_ids = case klass
                   when 'Source'
                     Language.used_recently_on_sources.where('project_sources.project_id = ? AND sources.updated_by_id = ?', project_id, user_id).pluck(:id).uniq
                   when 'Serial'
                     Language.used_recently_on_serials.where('serials.updated_by_id = ?', user_id).pluck(:id).uniq
                   when 'AlternateValue'
                     Language.used_recently_on_alternate_values.where('alternate_values.updated_by_id = ?', user_id).pluck(:id).uniq
                   when 'CommonNames'
                     Language.used_recently_on_alternate_values.where('alternate_values.updated_by_id = ?', user_id).pluck(:id).uniq
                   end

    h = {
      recent: Language.where(id: language_ids.first(10)).order(:english_name).to_a,
      pinboard: Language.pinned_by(user_id).pinned_in_project(project_id).to_a,
      quick: (Language.pinned_by(user_id).pinboard_inserted.pinned_in_project(project_id).to_a + Language.where(id: language_ids.first(4)).order(:english_name).to_a).uniq
    }
    h
  end
end