Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/models/card_card_subtype.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ class CardCardSubtype < ApplicationRecord
belongs_to :card_subtype,
:primary_key => :id,
:foreign_key => :card_subtype_id
end
belongs_to :unified_card,
:primary_key => :id,
:foreign_key => :card_id
end
1 change: 1 addition & 0 deletions app/models/card_cycle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class CardCycle < ApplicationRecord
has_many :card_sets
has_many :printings, :through => :card_sets
has_many :cards, :through => :printings
has_many :unified_cards, :through => :printings
has_many :card_pool_card_cycles
has_many :card_pools, :through => :card_pool_card_cycles
end
1 change: 1 addition & 0 deletions app/models/card_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class CardPool < ApplicationRecord
has_many :card_sets, :through => :card_pool_card_sets
has_many :card_pool_cards
has_many :cards, :through => :card_pool_cards
has_many :unified_cards, :through => :card_pool_cards, primary_key: :card_id, foreign_key: :id
has_many :snapshots

belongs_to :format,
Expand Down
5 changes: 4 additions & 1 deletion app/models/card_pool_card.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ class CardPoolCard < ApplicationRecord
belongs_to :card_pool,
:primary_key => :id,
:foreign_key => :card_pool_id
end
belongs_to :unified_card,
:primary_key => :id,
:foreign_key => :card_id
end
1 change: 1 addition & 0 deletions app/models/card_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ class CardSet < ApplicationRecord

has_many :printings
has_many :cards, :through => :printings
has_many :unified_cards, :through => :printings
end
1 change: 1 addition & 0 deletions app/models/card_subtype.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ class CardSubtype < ApplicationRecord
has_many :card_card_subtypes
has_many :cards, :through => :card_card_subtypes
has_many :printings, :through => :cards
has_many :unified_cards, :through => :card_card_subtypes, primary_key: :card_id, foreign_key: :id
end
1 change: 1 addition & 0 deletions app/models/card_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
class CardType < ApplicationRecord
belongs_to :side
has_many :cards
has_many :unified_cards
end
1 change: 1 addition & 0 deletions app/models/faction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ class Faction < ApplicationRecord
belongs_to :side
has_many :cards
has_many :printings, :through => :cards
has_many :unified_cards
end
1 change: 1 addition & 0 deletions app/models/printing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class Printing < ApplicationRecord
belongs_to :card
belongs_to :card_set
belongs_to :unified_card, primary_key: :id, foreign_key: :card_id
has_one :faction, :through => :card
has_one :card_cycle, :through => :card_set
has_one :side, :through => :card
Expand Down
1 change: 1 addition & 0 deletions app/models/side.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ class Side < ApplicationRecord
has_many :factions
has_many :card_types
has_many :cards
has_many :unified_cards
has_many :printings, :through => :cards
end
1 change: 1 addition & 0 deletions app/models/snapshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ class Snapshot < ApplicationRecord
belongs_to :card_pool
belongs_to :restriction, optional: :true
has_many :cards, through: :card_pool
has_many :unified_cards, through: :card_pool, primary_key: :card_id, foreign_key: :id
end
3 changes: 3 additions & 0 deletions app/models/unified_card.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class UnifiedCard < ApplicationRecord
self.primary_key = :id
end
3 changes: 2 additions & 1 deletion app/resources/api/v3/public/card_cycle_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class Api::V3::Public::CardCycleResource < JSONAPI::Resource

has_many :card_sets
has_many :printings
has_many :cards

has_many :cards, relation_name: :unified_cards

paginator :none
end
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/card_pool_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Api::V3::Public::CardPoolResource < JSONAPI::Resource
has_one :format
has_many :card_cycles
has_many :card_sets
has_many :cards
has_many :cards, relation_name: :unified_cards
has_many :snapshots

def num_cards
Expand Down
31 changes: 26 additions & 5 deletions app/resources/api/v3/public/card_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ module Public
class Api::V3::Public::CardResource < JSONAPI::Resource
immutable

model_name 'UnifiedCard'

attributes :stripped_title, :title, :card_type_id, :side_id, :faction_id
attributes :advancement_requirement, :agenda_points, :base_link, :cost
attributes :deck_limit, :influence_cost, :influence_limit, :memory_cost
attributes :minimum_deck_size, :strength, :stripped_text, :text, :trash_cost
attributes :is_unique, :display_subtypes, :updated_at
attributes :card_abilities, :latest_printing_id
attributes :deck_limit, :in_restriction, :influence_cost, :influence_limit, :memory_cost
attributes :minimum_deck_size, :latest_printing_id, :num_printings, :printing_ids, :restriction_ids, :restrictions, :strength, :stripped_text, :text, :trash_cost
attributes :is_unique, :card_subtype_ids, :display_subtypes, :updated_at
attributes :card_abilities, :format_ids, :card_pool_ids, :snapshot_ids

key_type :string

Expand All @@ -20,7 +22,7 @@ class Api::V3::Public::CardResource < JSONAPI::Resource
has_many :printings

def latest_printing_id
@model.printings.max_by { |p| p.date_release } ['id']
@model.printing_ids[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this now guaranteed to be enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused me to look at the view definition again. I was sorting by printing id descending, but i changed to use date_release DESC instead. Results are the same, but it communicates the intent more clearly.

Since the view has the field sorted, taking the first will be correct.

end

def card_abilities
Expand All @@ -39,6 +41,25 @@ def card_abilities
}
end

def packed_restriction_to_map(packed)
m = {}
packed.each do |p|
x = p.split('=')
m[x[0]] = x[1].to_i
end
return m
end

def restrictions
{
banned: @model.restrictions_banned,
global_penalty: @model.restrictions_global_penalty,
points: packed_restriction_to_map(@model.restrictions_points),
restricted: @model.restrictions_restricted,
universal_faction_cost: packed_restriction_to_map(@model.restrictions_universal_faction_cost)
}
end

filters :title, :card_type_id, :side_id, :faction_id, :advancement_requirement
filters :agenda_points, :base_link, :cost, :deck_limit, :influence_cost
filters :influence_limit, :memory_cost, :minimum_deck_size, :strength, :trash_cost, :is_unique
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/card_set_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Api::V3::Public::CardSetResource < JSONAPI::Resource
has_one :card_cycle
has_one :card_set_type
has_many :printings
has_many :cards
has_many :cards, relation_name: :unified_cards

filters :card_cycle_id, :card_set_type_id
end
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/card_subtype_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Api::V3::Public::CardSubtypeResource < JSONAPI::Resource

paginator :none

has_many :cards
has_many :cards, relation_name: :unified_cards
has_many :printings
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/card_type_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Api::V3::Public::CardTypeResource < JSONAPI::Resource
key_type :string

has_one :side
has_many :cards
has_many :cards, relation_name: :unified_cards
paginator :none

filter :side_id
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/faction_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Api::V3::Public::FactionResource < JSONAPI::Resource
paginator :none

has_one :side
has_many :cards
has_many :cards, relation_name: :unified_cards
has_many :printings

filters :side_id, :is_mini
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/side_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Api::V3::Public::SideResource < JSONAPI::Resource

has_many :factions
has_many :card_types
has_many :cards
has_many :cards, relation_name: :unified_cards
has_many :printings
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/resources/api/v3/public/snapshot_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Api::V3::Public::SnapshotResource < JSONAPI::Resource
has_one :card_pool
has_one :restriction

has_many :cards
has_many :cards, relation_name: :unified_cards

filters :active, :format_id

Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20220926010740_create_unified_cards.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class CreateUnifiedCards < ActiveRecord::Migration[7.0]
def change
create_view :unified_cards, materialized: true
end
end
158 changes: 157 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2022_09_25_225117) do
ActiveRecord::Schema[7.0].define(version: 2022_09_26_010740) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -320,4 +320,160 @@
add_index "unified_restrictions", ["restriction_id"], name: "index_unified_restrictions_on_restriction_id"
add_index "unified_restrictions", ["snapshot_id"], name: "index_unified_restrictions_on_snapshot_id"

create_view "unified_cards", materialized: true, sql_definition: <<-SQL
WITH card_cycles_summary AS (
SELECT c_1.id,
array_agg(cc.id ORDER BY cc.id) AS card_cycle_ids,
array_agg(lower(cc.name) ORDER BY (lower(cc.name))) AS card_cycle_names
FROM (((cards c_1
JOIN printings p_1 ON (((c_1.id)::text = p_1.card_id)))
JOIN card_sets cs ON ((p_1.card_set_id = (cs.id)::text)))
JOIN card_cycles cc ON (((cc.id)::text = cs.card_cycle_id)))
GROUP BY c_1.id
), card_sets_summary AS (
SELECT c_1.id,
array_agg(cs.id ORDER BY cs.id) AS card_set_ids,
array_agg(lower(cs.name) ORDER BY (lower(cs.name))) AS card_set_names
FROM ((cards c_1
JOIN printings p_1 ON (((c_1.id)::text = p_1.card_id)))
JOIN card_sets cs ON ((p_1.card_set_id = (cs.id)::text)))
GROUP BY c_1.id
), card_subtype_ids AS (
SELECT cards_card_subtypes.card_id,
array_agg(cards_card_subtypes.card_subtype_id ORDER BY 1::integer) AS card_subtype_ids
FROM cards_card_subtypes
GROUP BY cards_card_subtypes.card_id
), card_subtype_names AS (
SELECT ccs_1.card_id,
array_agg(lower(cs.name) ORDER BY (lower(cs.name))) AS lower_card_subtype_names,
array_agg(cs.name ORDER BY cs.name) AS card_subtype_names
FROM (cards_card_subtypes ccs_1
JOIN card_subtypes cs ON ((ccs_1.card_subtype_id = (cs.id)::text)))
GROUP BY ccs_1.card_id
), card_printing_ids AS (
SELECT printings.card_id,
array_agg(printings.id ORDER BY printings.date_release DESC) AS printing_ids
FROM printings
GROUP BY printings.card_id
), card_restriction_ids AS (
SELECT unified_restrictions.card_id,
array_agg(unified_restrictions.restriction_id ORDER BY unified_restrictions.restriction_id) AS restriction_ids
FROM unified_restrictions
WHERE unified_restrictions.in_restriction
GROUP BY unified_restrictions.card_id
), restrictions_banned_summary AS (
SELECT restrictions_cards_banned.card_id,
array_agg(restrictions_cards_banned.restriction_id ORDER BY restrictions_cards_banned.restriction_id) AS restrictions_banned
FROM restrictions_cards_banned
GROUP BY restrictions_cards_banned.card_id
), restrictions_global_penalty_summary AS (
SELECT restrictions_cards_global_penalty.card_id,
array_agg(restrictions_cards_global_penalty.restriction_id ORDER BY restrictions_cards_global_penalty.restriction_id) AS restrictions_global_penalty
FROM restrictions_cards_global_penalty
GROUP BY restrictions_cards_global_penalty.card_id
), restrictions_points_summary AS (
SELECT restrictions_cards_points.card_id,
array_agg(concat(restrictions_cards_points.restriction_id, '=', (restrictions_cards_points.value)::text) ORDER BY (concat(restrictions_cards_points.restriction_id, '=', (restrictions_cards_points.value)::text))) AS restrictions_points
FROM restrictions_cards_points
GROUP BY restrictions_cards_points.card_id
), restrictions_restricted_summary AS (
SELECT restrictions_cards_restricted.card_id,
array_agg(restrictions_cards_restricted.restriction_id ORDER BY restrictions_cards_restricted.restriction_id) AS restrictions_restricted
FROM restrictions_cards_restricted
GROUP BY restrictions_cards_restricted.card_id
), restrictions_universal_faction_cost_summary AS (
SELECT restrictions_cards_universal_faction_cost.card_id,
array_agg(concat(restrictions_cards_universal_faction_cost.restriction_id, '=', (restrictions_cards_universal_faction_cost.value)::text) ORDER BY (concat(restrictions_cards_universal_faction_cost.restriction_id, '=', (restrictions_cards_universal_faction_cost.value)::text))) AS restrictions_universal_faction_cost
FROM restrictions_cards_universal_faction_cost
GROUP BY restrictions_cards_universal_faction_cost.card_id
), format_ids AS (
SELECT cpc_1.card_id,
array_agg(DISTINCT s_1.format_id ORDER BY s_1.format_id) AS format_ids
FROM (card_pools_cards cpc_1
JOIN snapshots s_1 ON ((cpc_1.card_pool_id = s_1.card_pool_id)))
GROUP BY cpc_1.card_id
), card_pool_ids AS (
SELECT cpc_1.card_id,
array_agg(DISTINCT s_1.card_pool_id ORDER BY s_1.card_pool_id) AS card_pool_ids
FROM (card_pools_cards cpc_1
JOIN snapshots s_1 ON ((cpc_1.card_pool_id = s_1.card_pool_id)))
GROUP BY cpc_1.card_id
), snapshot_ids AS (
SELECT cpc_1.card_id,
array_agg(DISTINCT s_1.id ORDER BY s_1.id) AS snapshot_ids
FROM (card_pools_cards cpc_1
JOIN snapshots s_1 ON ((cpc_1.card_pool_id = s_1.card_pool_id)))
GROUP BY cpc_1.card_id
)
SELECT c.id,
c.title,
c.stripped_title,
c.card_type_id,
c.side_id,
c.faction_id,
c.advancement_requirement,
c.agenda_points,
c.base_link,
c.cost,
c.deck_limit,
c.influence_cost,
c.influence_limit,
c.memory_cost,
c.minimum_deck_size,
c.strength,
c.stripped_text,
c.text,
c.trash_cost,
c.is_unique,
c.display_subtypes,
c.created_at,
c.updated_at,
c.additional_cost,
c.advanceable,
c.gains_subroutines,
c.interrupt,
c.link_provided,
c.mu_provided,
c.num_printed_subroutines,
c.on_encounter_effect,
c.performs_trace,
c.recurring_credits_provided,
c.rez_effect,
c.trash_ability,
COALESCE(csi.card_subtype_ids, ARRAY[]::text[]) AS card_subtype_ids,
COALESCE(csn.lower_card_subtype_names, ARRAY[]::text[]) AS lower_card_subtype_names,
COALESCE(csn.card_subtype_names, ARRAY[]::text[]) AS card_subtype_names,
p.printing_ids,
array_length(p.printing_ids, 1) AS num_printings,
ccs.card_cycle_ids,
ccs.card_cycle_names,
css.card_set_ids,
css.card_set_names,
COALESCE(r.restriction_ids, (ARRAY[]::text[])::character varying[]) AS restriction_ids,
(r.restriction_ids IS NOT NULL) AS in_restriction,
COALESCE(r_b.restrictions_banned, ARRAY[]::text[]) AS restrictions_banned,
COALESCE(r_g_p.restrictions_global_penalty, ARRAY[]::text[]) AS restrictions_global_penalty,
COALESCE(r_p.restrictions_points, ARRAY[]::text[]) AS restrictions_points,
COALESCE(r_r.restrictions_restricted, ARRAY[]::text[]) AS restrictions_restricted,
COALESCE(r_u_f_c.restrictions_universal_faction_cost, ARRAY[]::text[]) AS restrictions_universal_faction_cost,
COALESCE(f.format_ids, ARRAY[]::text[]) AS format_ids,
COALESCE(cpc.card_pool_ids, ARRAY[]::text[]) AS card_pool_ids,
COALESCE(s.snapshot_ids, (ARRAY[]::text[])::character varying[]) AS snapshot_ids
FROM ((((((((((((((cards c
JOIN card_printing_ids p ON (((c.id)::text = p.card_id)))
JOIN card_cycles_summary ccs ON (((c.id)::text = (ccs.id)::text)))
JOIN card_sets_summary css ON (((c.id)::text = (css.id)::text)))
LEFT JOIN card_subtype_ids csi ON (((c.id)::text = csi.card_id)))
LEFT JOIN card_subtype_names csn ON (((c.id)::text = csn.card_id)))
LEFT JOIN card_restriction_ids r ON (((c.id)::text = (r.card_id)::text)))
LEFT JOIN restrictions_banned_summary r_b ON (((c.id)::text = r_b.card_id)))
LEFT JOIN restrictions_global_penalty_summary r_g_p ON (((c.id)::text = r_g_p.card_id)))
LEFT JOIN restrictions_points_summary r_p ON (((c.id)::text = r_p.card_id)))
LEFT JOIN restrictions_restricted_summary r_r ON (((c.id)::text = r_r.card_id)))
LEFT JOIN restrictions_universal_faction_cost_summary r_u_f_c ON (((c.id)::text = r_u_f_c.card_id)))
LEFT JOIN format_ids f ON (((c.id)::text = f.card_id)))
LEFT JOIN card_pool_ids cpc ON (((c.id)::text = cpc.card_id)))
LEFT JOIN snapshot_ids s ON (((c.id)::text = s.card_id)))
GROUP BY c.id, c.title, c.stripped_title, c.card_type_id, c.side_id, c.faction_id, c.advancement_requirement, c.agenda_points, c.base_link, c.cost, c.deck_limit, c.influence_cost, c.influence_limit, c.memory_cost, c.minimum_deck_size, c.strength, c.stripped_text, c.text, c.trash_cost, c.is_unique, c.display_subtypes, c.created_at, c.updated_at, c.additional_cost, c.advanceable, c.gains_subroutines, c.interrupt, c.link_provided, c.mu_provided, c.num_printed_subroutines, c.on_encounter_effect, c.performs_trace, c.recurring_credits_provided, c.rez_effect, c.trash_ability, csi.card_subtype_ids, csn.lower_card_subtype_names, csn.card_subtype_names, p.printing_ids, ccs.card_cycle_ids, ccs.card_cycle_names, css.card_set_ids, css.card_set_names, r.restriction_ids, r_b.restrictions_banned, r_g_p.restrictions_global_penalty, r_p.restrictions_points, r_r.restrictions_restricted, r_u_f_c.restrictions_universal_faction_cost, f.format_ids, cpc.card_pool_ids, s.snapshot_ids;
SQL
end
Loading