Files
MatchLiveTv/backend/app/models/team_roster_member.rb
T
eminuxandCursor b88f44ab1c Completa i18n IT/EN/FR/DE/ES su sito pubblico, area autenticata e admin.
Tutte le view marketing, legali, viewer, dashboard e admin usano t(); mailer utente-facing e flash localizzati; admin con LocaleResolver e selettore lingua.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:38:50 +02:00

81 lines
2.3 KiB
Ruby

class TeamRosterMember < ApplicationRecord
CATEGORIES = %w[staff coach manager player].freeze
# Ordine di visualizzazione in pagina organico
DISPLAY_ORDER = %w[coach manager player staff].freeze
def self.category_label(category)
I18n.t("roster.category.#{category}", default: category.to_s.capitalize)
end
VOLLEYBALL_PLAYER_ROLES = Sports::PlayerRoles::BY_BOARD["volley"].freeze
belongs_to :team
has_one_attached :photo_file
validates :full_name, presence: true
validates :category, inclusion: { in: CATEGORIES }
validates :jersey_number, numericality: { only_integer: true, greater_than: 0, less_than: 100 }, allow_nil: true
validate :photo_file_type, if: -> { photo_file.attached? }
validate :player_role_label_valid, if: -> { category == "player" && role_label.present? }
before_validation :assign_position, on: :create
scope :ordered, -> { order(:position, :created_at) }
scope :by_category, ->(cat) { where(category: cat).ordered }
def category_label
self.class.category_label(category)
end
def initials
parts = full_name.to_s.split(/\s+/).reject(&:blank?)
return "?" if parts.empty?
parts.first(2).map { |p| p[0] }.join.upcase
end
def photo_url
return unless photo_file.attached?
Rails.application.routes.url_helpers.rails_blob_path(photo_file, only_path: true)
end
def display_role
role_label.presence || default_role_label
end
private
def assign_position
return if position.positive? || team.blank?
max_pos = team.roster_members.where(category: category).maximum(:position) || -1
self.position = max_pos + 1
end
def default_role_label
case category
when "coach" then I18n.t("roster.role.coach")
when "manager" then I18n.t("roster.role.manager")
when "staff" then I18n.t("roster.role.staff")
when "player"
jersey_number.present? ? I18n.t("roster.role.player_numbered", number: jersey_number) : I18n.t("roster.role.player")
else category
end
end
def player_role_label_valid
allowed = Sports::PlayerRoles.for_team(team)
return if role_label.in?(allowed)
errors.add(:role_label, I18n.t("roster.errors.role_invalid"))
end
def photo_file_type
return if photo_file.content_type.in?(%w[image/png image/jpeg image/webp])
errors.add(:photo_file, I18n.t("roster.errors.photo_invalid_type"))
end
end