mirror of
https://github.com/ryankazokas/turbovault-app.git
synced 2026-04-17 02:52:55 +00:00
Moving to github
This commit is contained in:
148
app/models/igdb_match_suggestion.rb
Normal file
148
app/models/igdb_match_suggestion.rb
Normal file
@@ -0,0 +1,148 @@
|
||||
class IgdbMatchSuggestion < ApplicationRecord
|
||||
# Associations
|
||||
belongs_to :game
|
||||
belongs_to :igdb_game, optional: true
|
||||
|
||||
# Enums
|
||||
enum :status, {
|
||||
pending: "pending",
|
||||
approved: "approved",
|
||||
rejected: "rejected"
|
||||
}, prefix: true
|
||||
|
||||
# Validations
|
||||
validates :igdb_id, presence: true
|
||||
validates :igdb_name, presence: true
|
||||
validates :game_id, uniqueness: { scope: :igdb_id }
|
||||
|
||||
# Scopes
|
||||
scope :pending_review, -> { status_pending.order(confidence_score: :desc, created_at: :asc) }
|
||||
scope :for_user, ->(user) { joins(:game).where(games: { user_id: user.id }) }
|
||||
scope :high_confidence, -> { where("confidence_score >= ?", 80.0) }
|
||||
|
||||
# Instance methods
|
||||
def approve!
|
||||
transaction do
|
||||
update!(status: "approved", reviewed_at: Time.current)
|
||||
|
||||
# Update the game with the matched IGDB ID
|
||||
game.update!(
|
||||
igdb_id: igdb_id,
|
||||
igdb_matched_at: Time.current,
|
||||
igdb_match_status: "matched",
|
||||
igdb_match_confidence: confidence_score
|
||||
)
|
||||
|
||||
# Find or create the IgdbGame record with full data
|
||||
igdb_game_record = IgdbGame.find_or_create_by!(igdb_id: igdb_id) do |ig|
|
||||
ig.name = igdb_name
|
||||
ig.slug = igdb_slug
|
||||
ig.cover_url = igdb_cover_url
|
||||
ig.summary = igdb_summary
|
||||
ig.first_release_date = igdb_release_date
|
||||
ig.last_synced_at = Time.current
|
||||
end
|
||||
|
||||
# Update summary if it wasn't already set
|
||||
if igdb_game_record.summary.blank? && igdb_summary.present?
|
||||
igdb_game_record.update(summary: igdb_summary)
|
||||
end
|
||||
|
||||
igdb_game_record.increment_match_count!
|
||||
|
||||
# Map and assign IGDB genres to the game
|
||||
sync_genres_to_game if igdb_genres.present?
|
||||
|
||||
# Reject all other pending suggestions for this game
|
||||
game.igdb_match_suggestions
|
||||
.where.not(id: id)
|
||||
.status_pending
|
||||
.update_all(
|
||||
status: "rejected",
|
||||
reviewed_at: Time.current
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def reject!
|
||||
transaction do
|
||||
update!(
|
||||
status: "rejected",
|
||||
reviewed_at: Time.current
|
||||
)
|
||||
|
||||
# Reject all other pending suggestions for this game
|
||||
game.igdb_match_suggestions
|
||||
.where.not(id: id)
|
||||
.status_pending
|
||||
.update_all(
|
||||
status: "rejected",
|
||||
reviewed_at: Time.current
|
||||
)
|
||||
|
||||
# Mark game as manually reviewed with no match (only if all suggestions rejected)
|
||||
if game.igdb_match_suggestions.status_pending.none?
|
||||
game.update!(
|
||||
igdb_match_status: "no_match",
|
||||
igdb_matched_at: Time.current
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cover_image_url(size = "cover_big")
|
||||
return nil unless igdb_cover_url.present?
|
||||
"https://images.igdb.com/igdb/image/upload/t_#{size}/#{igdb_cover_url}.jpg"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sync_genres_to_game
|
||||
return unless igdb_genres.is_a?(Array) && igdb_genres.any?
|
||||
|
||||
# Genre mapping: IGDB genre names to our genre names
|
||||
genre_mappings = {
|
||||
"Role-playing (RPG)" => "RPG",
|
||||
"Fighting" => "Fighting",
|
||||
"Shooter" => "Shooter",
|
||||
"Music" => "Music",
|
||||
"Platform" => "Platformer",
|
||||
"Puzzle" => "Puzzle",
|
||||
"Racing" => "Racing",
|
||||
"Real Time Strategy (RTS)" => "Strategy",
|
||||
"Simulator" => "Simulation",
|
||||
"Sport" => "Sports",
|
||||
"Strategy" => "Strategy",
|
||||
"Turn-based strategy (TBS)" => "Strategy",
|
||||
"Tactical" => "Strategy",
|
||||
"Hack and slash/Beat 'em up" => "Action",
|
||||
"Quiz/Trivia" => "Puzzle",
|
||||
"Pinball" => "Arcade",
|
||||
"Adventure" => "Adventure",
|
||||
"Indie" => "Indie",
|
||||
"Arcade" => "Arcade",
|
||||
"Visual Novel" => "Adventure",
|
||||
"Card & Board Game" => "Puzzle",
|
||||
"MOBA" => "Strategy",
|
||||
"Point-and-click" => "Adventure"
|
||||
}
|
||||
|
||||
# Find or create matching genres
|
||||
igdb_genres.each do |igdb_genre_name|
|
||||
# Try exact match first
|
||||
local_genre = Genre.find_by("LOWER(name) = ?", igdb_genre_name.downcase)
|
||||
|
||||
# Try mapped name
|
||||
if local_genre.nil? && genre_mappings[igdb_genre_name]
|
||||
mapped_name = genre_mappings[igdb_genre_name]
|
||||
local_genre = Genre.find_by("LOWER(name) = ?", mapped_name.downcase)
|
||||
end
|
||||
|
||||
# Add genre to game if found and not already assigned
|
||||
if local_genre && !game.genres.include?(local_genre)
|
||||
game.genres << local_genre
|
||||
Rails.logger.info("Added genre '#{local_genre.name}' to game #{game.id} from IGDB")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user