<commit_before>module People
  module Numbers
    extend ActiveSupport::Concern

    included do
      has_many :race_numbers, -> { includes(:discipline, :number_issuer) }, dependent: :destroy

      accepts_nested_attributes_for :race_numbers,
        reject_if: proc { |attributes| !attributes.has_key?(:value) || attributes[:value].blank? }

      def self.find_all_by_number(number)
        RaceNumber.
          includes(:person).
          where(year: [ RacingAssociation.current.year, RacingAssociation.current.next_year ]).
          where(value: number).
          map(&:person)
      end
    end

    def number(discipline_param, reload = false, year = nil)
      return nil if discipline_param.nil?

      year ||= RacingAssociation.current.year
      if discipline_param.is_a?(Discipline)
        discipline_param = discipline_param.to_param
      end
      number = race_numbers(reload).detect do |race_number|
        race_number.year == year &&
        race_number.discipline_id == RaceNumber.discipline_id(discipline_param) &&
        race_number.number_issuer.name == RacingAssociation.current.short_name
      end
      number.try :value
    end

    # Look for RaceNumber +year+ in +attributes+. Not sure if there's a simple and better way to do that.
    # Need to set +updated_by+ before setting numbers to ensure updated_by is passed to number. Setting all via a
    # parameter hash may add number before updated_by is set.
    def add_number(value, discipline, association = nil, _year = year)
      association = NumberIssuer.find_by_name(RacingAssociation.current.short_name) if association.nil?
      _year ||= RacingAssociation.current.year

      if discipline.nil? || !discipline.numbers?
        discipline = Discipline[:road]
      end

      if value.blank?
        unless new_record?
          # Delete ALL numbers for RacingAssociation.current and this discipline?
          # FIXME Delete number individually in UI
          RaceNumber.destroy_all(
            ['person_id=? and discipline_id=? and year=? and number_issuer_id=?',
            self.id, discipline.id, _year, association.id])
        end
      else
        if new_record?
          existing_number = race_numbers.any? do |number|
            number.value == value && number.discipline == discipline && number.association == association && number.year == _year
          end
          race_numbers.build(
            value: value, discipline: discipline, year: _year, number_issuer: association,
            person: self,
            updated_by: updated_by
          ) unless existing_number
        else
          RaceNumber.where(
            value: value, person_id: id, discipline_id: discipline.id, year: _year, number_issuer_id: association.id
          ).first || race_numbers.create(
            value: value, discipline: discipline, year: _year, number_issuer: association, person: self, updated_by: updated_by
          )
        end
      end
    end

    def bmx_number(reload = false, year = nil)
      number(Discipline[:bmx], reload, year)
    end

    def ccx_number(reload = false, year = nil)
      number(Discipline[:cyclocross], reload, year)
    end

    def dh_number(reload = false, year = nil)
      number(Discipline[:downhill], reload, year)
    end

    def road_number(reload = false, year = nil)
      number(Discipline[:road], reload, year)
    end

    def singlespeed_number(reload = false, year = nil)
      number(Discipline[:singlespeed], reload, year)
    end

    def track_number(reload = false, year = nil)
      number(Discipline[:track], reload, year)
    end
<commit_msg>Decompose number-adding into sensible methods<commit_after>module People
  module Numbers
    extend ActiveSupport::Concern

    included do
      has_many :race_numbers, -> { includes(:discipline, :number_issuer) }, dependent: :destroy

      accepts_nested_attributes_for :race_numbers,
        reject_if: proc { |attributes| !attributes.has_key?(:value) || attributes[:value].blank? }

      def self.find_all_by_number(number)
        RaceNumber.
          includes(:person).
          where(year: [ RacingAssociation.current.year, RacingAssociation.current.next_year ]).
          where(value: number).
          map(&:person)
      end
    end

    def number(discipline_param, reload = false, year = nil)
      return nil if discipline_param.nil?

      year ||= RacingAssociation.current.year
      if discipline_param.is_a?(Discipline)
        discipline_param = discipline_param.to_param
      end
      number = race_numbers(reload).detect do |race_number|
        race_number.year == year &&
        race_number.discipline_id == RaceNumber.discipline_id(discipline_param) &&
        race_number.number_issuer.name == RacingAssociation.current.short_name
      end
      number.try :value
    end

    # Look for RaceNumber +year+ in +attributes+. Not sure if there's a simple and better way to do that.
    # Need to set +updated_by+ before setting numbers to ensure updated_by is passed to number. Setting all via a
    # parameter hash may add number before updated_by is set.
    def add_number(value, discipline, issuer = nil, _year = year)
      return false if discipline.blank? && value.blank?

      if discipline.nil? || !discipline.numbers?
        discipline = Discipline[:road]
      end
      issuer = NumberIssuer.find_by_name(RacingAssociation.current.short_name) if issuer.nil?
      _year ||= RacingAssociation.current.year

      if value.present?
        if new_record?
          build_number value, discipline, issuer, updated_by, _year
        else
          create_number value, discipline, issuer, updated_by, _year
        end
      else
        if !new_record?
          destroy_number discipline, issuer, _year
        end
      end
    end

    def build_number(value, discipline, issuer, updated_by, year)
      unless race_number?(value, discipline, issuer, year)
        race_numbers.build(
          discipline: discipline,
          number_issuer: issuer,
          person: self,
          updated_by: updated_by,
          value: value,
          year: year
        )
      end
    end

    def create_number(value, discipline, issuer, updated_by, year)
      unless race_number?(value, discipline, issuer, year)
        race_numbers.create(
          discipline: discipline,
          number_issuer: issuer,
          person: self,
          updated_by: updated_by,
          value: value,
          year: year
        )
      end
    end

    def destroy_number(discipline, issuer, year)
      RaceNumber.where(discipline: discipline, number_issuer: issuer, person: self, year: year).destroy_all
    end

    def race_number?(value, discipline, issuer, year)
      if new_record?
        race_numbers.any? do |n|
          n.value == value &&
          n.discipline == discipline &&
          n.number_issuer == issuer &&
          n.year == year
        end
      else
        RaceNumber.where(
          discipline: discipline,
          number_issuer: issuer,
          person: self,
          value: value,
          year: year
        ).exists?
      end
    end

    def bmx_number(reload = false, year = nil)
      number(Discipline[:bmx], reload, year)
    end

    def ccx_number(reload = false, year = nil)
      number(Discipline[:cyclocross], reload, year)
    end

    def dh_number(reload = false, year = nil)
      number(Discipline[:downhill], reload, year)
    end

    def road_number(reload = false, year = nil)
      number(Discipline[:road], reload, year)
    end

    def singlespeed_number(reload = false, year = nil)
      number(Discipline[:singlespeed], reload, year)
    end

    def track_number(reload = false, year = nil)
      number(Discipline[:track], reload, year)
    end

{'fraction_non_alphanumeric': 0.08857988927513841, 'fraction_numerical': 0.0, 'mean_word_length': 2.5979620194534507, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '5803453', 'n_tokens_mistral': 2265, 'n_tokens_neox': 2169, 'n_words': 591}