<commit_before># == Schema Information
#
# Table name: current_stops
#
#  id                                 :integer          not null, primary key
#  onestop_id                         :string
#  geometry                           :geography({:srid geometry, 4326
#  tags                               :hstore
#  created_at                         :datetime
#  updated_at                         :datetime
#  name                               :string
#  created_or_updated_in_changeset_id :integer
#  version                            :integer
#  identifiers                        :string           default([]), is an Array
#  timezone                           :string
#  last_conflated_at                  :datetime
#  type                               :string
#  parent_stop_id                     :integer
#  osm_way_id                         :integer
#
# Indexes
#
#  #c_stops_cu_in_changeset_id_index      (created_or_updated_in_changeset_id)
#  index_current_stops_on_geometry        (geometry)
#  index_current_stops_on_identifiers     (identifiers)
#  index_current_stops_on_onestop_id      (onestop_id)
#  index_current_stops_on_parent_stop_id  (parent_stop_id)
#  index_current_stops_on_tags            (tags)
#  index_current_stops_on_updated_at      (updated_at)
#

class BaseStop < ActiveRecord::Base
  self.abstract_class = true
end

class Stop < BaseStop
  self.table_name = 'current_stops'
  attr_accessor :served_by, :not_served_by
  attr_accessor :includes_stop_transfers, :does_not_include_stop_transfers
  validates :timezone, presence: true

  include HasAOnestopId
  include IsAnEntityWithIdentifiers
  include HasAGeographicGeometry
  include HasTags
  include UpdatedSince
  include IsAnEntityImportedFromFeeds

  include CanBeSerializedToCsv
  def self.csv_column_names
    [
      'Onestop ID',
      'Name',
      'Operators serving stop (names)',
      'Operators serving stop (Onestop IDs)',
      'Latitude (centroid)',
      'Longitude (centroid)'
    ]
  end
  def csv_row_values
    [
      onestop_id,
      name,
      operators_serving_stop.map {|oss| oss.operator.name }.join(', '),
      operators_serving_stop.map {|oss| oss.operator.onestop_id }.join(', '),
      geometry_centroid[:lat],
      geometry_centroid[:lon]
    ]
  end

  include CurrentTrackedByChangeset
  current_tracked_by_changeset({
    kind_of_model_tracked: :onestop_entity,
    virtual_attributes: [
      :served_by,
      :not_served_by,
      :identified_by,
      :not_identified_by,
      :includes_stop_transfers,
      :does_not_include_stop_transfers
    ],
    protected_attributes: [
      :identifiers,
      :last_conflated_at,
      :type
    ]
  })

  def after_create_making_history(changeset)
    super(changeset)
    update_served_by(changeset)
    update_includes_stop_transfers(changeset)
    update_does_not_include_stop_transfers(changeset)
  end
  def before_update_making_history(changeset)
    super(changeset)
    update_served_by(changeset)
    update_includes_stop_transfers(changeset)
    update_does_not_include_stop_transfers(changeset)
  end
  def before_destroy_making_history(changeset, old_model)
    operators_serving_stop.each do |operator_serving_stop|
      operator_serving_stop.destroy_making_history(changeset: changeset)
    end
    routes_serving_stop.each do |route_serving_stop|
      route_serving_stop.destroy_making_history(changeset: changeset)
    end
    return true
  end

  # Operators serving this stop
  has_many :operators_serving_stop
  has_many :operators, through: :operators_serving_stop

  # Routes serving this stop
  has_many :routes_serving_stop
  has_many :routes, through: :routes_serving_stop

  def operators_serving_stop_and_platforms
    OperatorServingStop
      .where('stop_id IN (?) OR stop_id = ?', Stop.where(parent_stop_id: self.id).select(:id), self.id)
      .select('DISTINCT ON (current_operators_serving_stop.operator_id) *')
  end

  def routes_serving_stop_and_platforms
    RouteServingStop
      .where('stop_id IN (?) OR stop_id = ?', Stop.where(parent_stop_id: self.id).select(:id), self.id)
      .select('DISTINCT ON (current_routes_serving_stop.route_id) *')
  end

  def vehicle_types_serving_stop_and_platforms
    routes_serving_stop_and_platforms.map(&:route).map(&:vehicle_type).uniq
  end

  # Route vehicle_type serving stop
  def served_by_vehicle_types<commit_msg>Stop: use cacheable relation for vehicle_types_serving_stop_and_platforms<commit_after># == Schema Information
#
# Table name: current_stops
#
#  id                                 :integer          not null, primary key
#  onestop_id                         :string
#  geometry                           :geography({:srid geometry, 4326
#  tags                               :hstore
#  created_at                         :datetime
#  updated_at                         :datetime
#  name                               :string
#  created_or_updated_in_changeset_id :integer
#  version                            :integer
#  identifiers                        :string           default([]), is an Array
#  timezone                           :string
#  last_conflated_at                  :datetime
#  type                               :string
#  parent_stop_id                     :integer
#  osm_way_id                         :integer
#
# Indexes
#
#  #c_stops_cu_in_changeset_id_index      (created_or_updated_in_changeset_id)
#  index_current_stops_on_geometry        (geometry)
#  index_current_stops_on_identifiers     (identifiers)
#  index_current_stops_on_onestop_id      (onestop_id)
#  index_current_stops_on_parent_stop_id  (parent_stop_id)
#  index_current_stops_on_tags            (tags)
#  index_current_stops_on_updated_at      (updated_at)
#

class BaseStop < ActiveRecord::Base
  self.abstract_class = true
end

class Stop < BaseStop
  self.table_name = 'current_stops'
  attr_accessor :served_by, :not_served_by
  attr_accessor :includes_stop_transfers, :does_not_include_stop_transfers
  validates :timezone, presence: true

  include HasAOnestopId
  include IsAnEntityWithIdentifiers
  include HasAGeographicGeometry
  include HasTags
  include UpdatedSince
  include IsAnEntityImportedFromFeeds

  include CanBeSerializedToCsv
  def self.csv_column_names
    [
      'Onestop ID',
      'Name',
      'Operators serving stop (names)',
      'Operators serving stop (Onestop IDs)',
      'Latitude (centroid)',
      'Longitude (centroid)'
    ]
  end
  def csv_row_values
    [
      onestop_id,
      name,
      operators_serving_stop.map {|oss| oss.operator.name }.join(', '),
      operators_serving_stop.map {|oss| oss.operator.onestop_id }.join(', '),
      geometry_centroid[:lat],
      geometry_centroid[:lon]
    ]
  end

  include CurrentTrackedByChangeset
  current_tracked_by_changeset({
    kind_of_model_tracked: :onestop_entity,
    virtual_attributes: [
      :served_by,
      :not_served_by,
      :identified_by,
      :not_identified_by,
      :includes_stop_transfers,
      :does_not_include_stop_transfers
    ],
    protected_attributes: [
      :identifiers,
      :last_conflated_at,
      :type
    ]
  })

  def after_create_making_history(changeset)
    super(changeset)
    update_served_by(changeset)
    update_includes_stop_transfers(changeset)
    update_does_not_include_stop_transfers(changeset)
  end
  def before_update_making_history(changeset)
    super(changeset)
    update_served_by(changeset)
    update_includes_stop_transfers(changeset)
    update_does_not_include_stop_transfers(changeset)
  end
  def before_destroy_making_history(changeset, old_model)
    operators_serving_stop.each do |operator_serving_stop|
      operator_serving_stop.destroy_making_history(changeset: changeset)
    end
    routes_serving_stop.each do |route_serving_stop|
      route_serving_stop.destroy_making_history(changeset: changeset)
    end
    return true
  end

  # Operators serving this stop
  has_many :operators_serving_stop
  has_many :operators, through: :operators_serving_stop

  # Routes serving this stop
  has_many :routes_serving_stop
  has_many :routes, through: :routes_serving_stop

  def operators_serving_stop_and_platforms
    OperatorServingStop
      .where('stop_id IN (?) OR stop_id = ?', Stop.where(parent_stop_id: self.id).select(:id), self.id)
      .select('DISTINCT ON (current_operators_serving_stop.operator_id) *')
  end

  def routes_serving_stop_and_platforms
    RouteServingStop
      .where('stop_id IN (?) OR stop_id = ?', Stop.where(parent_stop_id: self.id).select(:id), self.id)
      .select('DISTINCT ON (current_routes_serving_stop.route_id) *')
  end

  def vehicle_types_serving_stop_and_platforms
    # Use cacheable relations
    (self.stop_platforms + [self]).map { |s| s.served_by_vehicle_types }.flatten.uniq
  end

  # Route vehicle_type serving stop
  def served_by_vehicle_types
{'fraction_non_alphanumeric': 0.07162192646063614, 'fraction_numerical': 0.0009023234829686443, 'mean_word_length': 2.951426024955437, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4074200', 'n_tokens_mistral': 2896, 'n_tokens_neox': 2814, 'n_words': 483}