add summon series lookup table
This commit is contained in:
parent
e7e9bd0f86
commit
3b5b8412d3
6 changed files with 182 additions and 0 deletions
22
app/blueprints/api/v1/summon_series_blueprint.rb
Normal file
22
app/blueprints/api/v1/summon_series_blueprint.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class SummonSeriesBlueprint < ApiBlueprint
|
||||
field :name do |ss|
|
||||
{
|
||||
en: ss.name_en,
|
||||
ja: ss.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
fields :slug, :order
|
||||
|
||||
view :full do
|
||||
field :summon_count do |ss|
|
||||
ss.summons.count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
72
app/controllers/api/v1/summon_series_controller.rb
Normal file
72
app/controllers/api/v1/summon_series_controller.rb
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class SummonSeriesController < Api::V1::ApiController
|
||||
before_action :set_summon_series, only: %i[show update destroy]
|
||||
before_action :ensure_editor_role, only: %i[create update destroy]
|
||||
|
||||
# GET /summon_series
|
||||
def index
|
||||
summon_series = SummonSeries.ordered
|
||||
render json: SummonSeriesBlueprint.render(summon_series)
|
||||
end
|
||||
|
||||
# GET /summon_series/:id
|
||||
def show
|
||||
render json: SummonSeriesBlueprint.render(@summon_series, view: :full)
|
||||
end
|
||||
|
||||
# POST /summon_series
|
||||
def create
|
||||
summon_series = SummonSeries.new(summon_series_params)
|
||||
|
||||
if summon_series.save
|
||||
render json: SummonSeriesBlueprint.render(summon_series, view: :full), status: :created
|
||||
else
|
||||
render_validation_error_response(summon_series)
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /summon_series/:id
|
||||
def update
|
||||
if @summon_series.update(summon_series_params)
|
||||
render json: SummonSeriesBlueprint.render(@summon_series, view: :full)
|
||||
else
|
||||
render_validation_error_response(@summon_series)
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /summon_series/:id
|
||||
def destroy
|
||||
if @summon_series.summons.exists?
|
||||
render json: ErrorBlueprint.render(nil, error: {
|
||||
message: 'Cannot delete series with associated summons',
|
||||
code: 'has_dependencies'
|
||||
}), status: :unprocessable_entity
|
||||
else
|
||||
@summon_series.destroy!
|
||||
head :no_content
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_summon_series
|
||||
# Support lookup by slug or UUID
|
||||
@summon_series = SummonSeries.find_by(slug: params[:id]) || SummonSeries.find(params[:id])
|
||||
end
|
||||
|
||||
def ensure_editor_role
|
||||
return if current_user&.role && current_user.role >= 7
|
||||
|
||||
Rails.logger.warn "[SUMMON_SERIES] Unauthorized access attempt by user #{current_user&.id}"
|
||||
render json: { error: 'Unauthorized - Editor role required' }, status: :unauthorized
|
||||
end
|
||||
|
||||
def summon_series_params
|
||||
params.require(:summon_series).permit(:name_en, :name_jp, :slug, :order)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
23
app/models/summon_series.rb
Normal file
23
app/models/summon_series.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SummonSeries < ApplicationRecord
|
||||
has_many :summons, dependent: :restrict_with_error
|
||||
|
||||
validates :name_en, presence: true
|
||||
validates :name_jp, presence: true
|
||||
validates :slug, presence: true, uniqueness: true
|
||||
validates :order, numericality: { only_integer: true }
|
||||
|
||||
scope :ordered, -> { order(:order) }
|
||||
|
||||
# Slug constants for commonly referenced series
|
||||
PROVIDENCE = 'providence'
|
||||
GENESIS = 'genesis'
|
||||
MAGNA = 'magna'
|
||||
OPTIMUS = 'optimus'
|
||||
ARCARUM = 'arcarum'
|
||||
|
||||
def blueprint
|
||||
SummonSeriesBlueprint
|
||||
end
|
||||
end
|
||||
41
db/data/20251214104722_create_summon_series_records.rb
Normal file
41
db/data/20251214104722_create_summon_series_records.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateSummonSeriesRecords < ActiveRecord::Migration[8.0]
|
||||
def up
|
||||
summon_series_data = [
|
||||
{ order: 0, slug: 'providence', name_en: 'Providence Series', name_jp: 'プロヴィデンスシリーズ' },
|
||||
{ order: 1, slug: 'genesis', name_en: 'Genesis Series', name_jp: 'ジェネシスシリーズ' },
|
||||
{ order: 2, slug: 'magna', name_en: 'Magna Series', name_jp: 'マグナシリーズ' },
|
||||
{ order: 3, slug: 'optimus', name_en: 'Optimus Series', name_jp: 'オプティマスシリーズ' },
|
||||
{ order: 4, slug: 'demi-optimus', name_en: 'Demi Optimus Series', name_jp: 'オプティマス・ディヴィジョン' },
|
||||
{ order: 5, slug: 'archangel', name_en: 'Archangel Series', name_jp: '天司シリーズ' },
|
||||
{ order: 6, slug: 'arcarum', name_en: 'Arcarum Series', name_jp: 'アーカルムシリーズ' },
|
||||
{ order: 7, slug: 'epic', name_en: 'Epic Series', name_jp: 'エピックシリーズ' },
|
||||
{ order: 8, slug: 'carbuncle', name_en: 'Carbuncle Series', name_jp: 'カーバンクルシリーズ' },
|
||||
{ order: 9, slug: 'dynamis', name_en: 'Dynamis Series', name_jp: 'デュナミスシリーズ' },
|
||||
{ order: 10, slug: 'cryptid', name_en: 'Cryptid Series', name_jp: 'UMAシリーズ' },
|
||||
{ order: 11, slug: 'six-dragons', name_en: 'Six Dragons', name_jp: '六竜シリーズ' },
|
||||
{ order: 12, slug: 'bellum', name_en: 'Bellum Series', name_jp: 'ベルムシリーズ' },
|
||||
{ order: 13, slug: 'crest', name_en: 'Crest Series', name_jp: 'クレストシリーズ' },
|
||||
{ order: 14, slug: 'robur', name_en: 'Robur Series', name_jp: 'ロブルシリーズ' },
|
||||
{ order: 15, slug: 'summer', name_en: 'Summer', name_jp: '水着' },
|
||||
{ order: 16, slug: 'yukata', name_en: 'Yukata', name_jp: '浴衣' },
|
||||
{ order: 17, slug: 'holiday', name_en: 'Holiday', name_jp: 'クリスマス' },
|
||||
{ order: 18, slug: 'collab', name_en: 'Collab', name_jp: 'コラボ' }
|
||||
]
|
||||
|
||||
puts 'Creating summon series records...'
|
||||
summon_series_data.each do |data|
|
||||
ss = SummonSeries.find_or_initialize_by(slug: data[:slug])
|
||||
ss.assign_attributes(data)
|
||||
ss.save!
|
||||
puts " #{ss.slug}: #{ss.name_en}"
|
||||
end
|
||||
|
||||
puts "\nCreated #{SummonSeries.count} summon series records"
|
||||
end
|
||||
|
||||
def down
|
||||
SummonSeries.delete_all
|
||||
end
|
||||
end
|
||||
15
db/migrate/20251214104720_create_summon_series.rb
Normal file
15
db/migrate/20251214104720_create_summon_series.rb
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateSummonSeries < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :summon_series, id: :uuid do |t|
|
||||
t.string :name_en, null: false
|
||||
t.string :name_jp, null: false
|
||||
t.string :slug, null: false
|
||||
t.integer :order, default: 0, null: false
|
||||
end
|
||||
|
||||
add_index :summon_series, :slug, unique: true
|
||||
add_index :summon_series, :order
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddSummonSeriesIdToSummons < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :summons, :summon_series_id, :uuid
|
||||
add_index :summons, :summon_series_id
|
||||
add_foreign_key :summons, :summon_series
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue