diff --git a/app/enumerations/item_types.rb b/app/enumerations/item_types.rb new file mode 100644 index 0000000..1eb2a6d --- /dev/null +++ b/app/enumerations/item_types.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ItemTypes < EnumerateIt::Base + associate_values :game, :game_bundle, :dlc, :dlc_bundle +end diff --git a/app/lib/nintendo/item_data_adapter.rb b/app/lib/nintendo/item_data_adapter.rb index 4c9d294..324de44 100644 --- a/app/lib/nintendo/item_data_adapter.rb +++ b/app/lib/nintendo/item_data_adapter.rb @@ -10,10 +10,10 @@ class ItemDataAdapter ].freeze IMAGE_BASE_URL = "https://assets.nintendo.com/image/upload/ar_16:9,b_auto:border,c_lpad/b_white/f_auto/q_auto/dpr_auto/c_scale,w_720/v1" ITEM_TYPES = { - nil => :game, - "Individual" => :dlc, - "Bundle" => :dlc_bundle, - "ROM Bundle" => :game_bundle + nil => ItemTypes::GAME, + "Individual" => ItemTypes::DLC, + "Bundle" => ItemTypes::DLC_BUNDLE, + "ROM Bundle" => ItemTypes::GAME_BUNDLE }.freeze def initialize(data) diff --git a/app/models/concerns/items/relations.rb b/app/models/concerns/items/relations.rb new file mode 100644 index 0000000..82df8a3 --- /dev/null +++ b/app/models/concerns/items/relations.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module Items + module Relations + extend ActiveSupport::Concern + + included do + has_one :raw_item, dependent: :destroy + has_one :price, dependent: :destroy + + has_many :wishlist_items, dependent: :destroy + has_many :parent_relationships, + class_name: "ItemRelationship", + foreign_key: :parent_id, + dependent: :destroy, + inverse_of: :parent + has_many :child_relationships, + class_name: "ItemRelationship", + foreign_key: :child_id, + dependent: :destroy, + inverse_of: :child + has_many :events, class_name: "ItemEvent", dependent: :destroy + + has_many :children, through: :parent_relationships, class_name: "Item", source: :child + has_many :parents, through: :child_relationships, class_name: "Item", source: :parent + has_many :price_history_items, through: :price, source: :history_items + end + end +end diff --git a/app/models/concerns/items/scopes.rb b/app/models/concerns/items/scopes.rb index edb0f1b..e448336 100644 --- a/app/models/concerns/items/scopes.rb +++ b/app/models/concerns/items/scopes.rb @@ -7,7 +7,7 @@ module Scopes extend ActiveSupport::Concern included do - scope :only_games, -> { where(item_type: %i[game game_bundle]) } + scope :only_games, -> { where(item_type: [ItemTypes::GAME, ItemTypes::GAME_BUNDLE]) } scope :with_nsuid, -> { where.not(nsuid: nil) } scope :on_sale, -> { where(on_sale: true) } scope :new_release, -> { where(new_release: true) } diff --git a/app/models/concerns/items/validations.rb b/app/models/concerns/items/validations.rb new file mode 100644 index 0000000..7aa9c14 --- /dev/null +++ b/app/models/concerns/items/validations.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module Items + module Validations + extend ActiveSupport::Concern + + included do + validates :item_type, presence: true + validates :title, presence: true + validates :external_id, presence: true + + validates :external_id, uniqueness: true + + validates :title, length: { maximum: 1024 } + validates :description, length: { maximum: 8192 } + validates :nsuid, length: { maximum: 32 } + validates :external_id, length: { maximum: 256 } + validates :release_date_display, length: { maximum: 64 } + end + end +end diff --git a/app/models/item.rb b/app/models/item.rb index 780aa7e..20c47bc 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -3,31 +3,13 @@ class Item < ApplicationRecord include FriendlyId include PgSearch::Model + include Items::Relations include Items::Scopes + include Items::Validations attribute :wishlisted, :boolean, default: false # this attr will be filled using WithWishlistedColumnQuery - has_one :raw_item, dependent: :destroy - has_one :price, dependent: :destroy - - has_many :wishlist_items, dependent: :destroy - has_many :parent_relationships, - class_name: "ItemRelationship", - foreign_key: :parent_id, - dependent: :destroy, - inverse_of: :parent - has_many :child_relationships, - class_name: "ItemRelationship", - foreign_key: :child_id, - dependent: :destroy, - inverse_of: :child - has_many :events, class_name: "ItemEvent", dependent: :destroy - - has_many :children, through: :parent_relationships, class_name: "Item", source: :child - has_many :parents, through: :child_relationships, class_name: "Item", source: :parent - has_many :price_history_items, through: :price, source: :history_items - - enum :item_type, game: 0, game_bundle: 1, dlc: 2, dlc_bundle: 3 + has_enumeration_for :item_type, with: ItemTypes, create_helpers: true, required: true, create_scopes: true friendly_id :title, use: :history @@ -35,18 +17,6 @@ class Item < ApplicationRecord pg_search_scope :search_by_title, against: :title, using: { tsearch: { dictionary: "english" } }, ignoring: :accents - validates :item_type, presence: true - validates :title, presence: true - validates :external_id, presence: true - - validates :external_id, uniqueness: true - - validates :title, length: { maximum: 1024 } - validates :description, length: { maximum: 8192 } - validates :nsuid, length: { maximum: 32 } - validates :external_id, length: { maximum: 256 } - validates :release_date_display, length: { maximum: 64 } - def to_param slug end diff --git a/config/locales/pt-BR/enumerations.yml b/config/locales/pt-BR/enumerations.yml index ea4bfa3..82e8f60 100644 --- a/config/locales/pt-BR/enumerations.yml +++ b/config/locales/pt-BR/enumerations.yml @@ -10,6 +10,12 @@ pt-BR: permanent_price_change: Reajuste de preço price_state_change: Remoção da eShop + item_types: + game: Jogo + game_bundle: 'Bundle' + dlc: 'DLC' + dlc_bundle: 'Bundle de DLC' + price_states: pre_order: Pré-venda on_sale: Disponível diff --git a/db/migrate/20221029000002_change_item_type_column_type.rb b/db/migrate/20221029000002_change_item_type_column_type.rb new file mode 100644 index 0000000..0407a71 --- /dev/null +++ b/db/migrate/20221029000002_change_item_type_column_type.rb @@ -0,0 +1,5 @@ +class ChangeItemTypeColumnType < ActiveRecord::Migration[7.0] + def change + change_column(:items, :item_type, :string) + end +end diff --git a/db/schema.rb b/db/schema.rb index 673cb8a..1b34af8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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_07_18_224212) do +ActiveRecord::Schema[7.0].define(version: 2022_10_29_000002) do # These are extensions that must be enabled in order to support this database enable_extension "citext" enable_extension "pgcrypto" @@ -90,7 +90,7 @@ t.string "developer" t.string "publisher" t.string "num_of_players" - t.integer "item_type", null: false + t.string "item_type", null: false t.string "bg_color" t.string "headline" t.string "video_urls", default: [], null: false, array: true diff --git a/spec/factories/items_factories.rb b/spec/factories/items_factories.rb index f3e3d87..84ffd47 100644 --- a/spec/factories/items_factories.rb +++ b/spec/factories/items_factories.rb @@ -2,7 +2,9 @@ FactoryBot.define do factory :item do - item_type { Item.item_types.keys.sample } + traits_for_enum :item_type, ItemTypes.list + + item_type { ItemTypes.list.sample } external_id { Faker::Internet.unique.uuid } title { Faker::Game.title } slug { title.parameterize } diff --git a/spec/lib/nintendo/item_data_adapter_spec.rb b/spec/lib/nintendo/item_data_adapter_spec.rb index a032bcd..5745509 100644 --- a/spec/lib/nintendo/item_data_adapter_spec.rb +++ b/spec/lib/nintendo/item_data_adapter_spec.rb @@ -5,34 +5,34 @@ RSpec.describe Nintendo::ItemDataAdapter, type: :lib do describe "#item_type" do context "when dlcType is nil" do - it "returns :game" do + it "returns ItemTypes::GAME" do adapted_data = described_class.adapt({ "dlcType" => nil }) - expect(adapted_data[:item_type]).to eq :game + expect(adapted_data[:item_type]).to eq ItemTypes::GAME end end context "when dlcType is Individual" do - it "returns :dlc" do + it "returns ItemTypes::DLC" do adapted_data = described_class.adapt({ "dlcType" => "Individual" }) - expect(adapted_data[:item_type]).to eq :dlc + expect(adapted_data[:item_type]).to eq ItemTypes::DLC end end context "when dlcType is Bundle" do - it "returns :dlc_bundler" do + it "returns ItemTypes::DLC_BUNDLE" do adapted_data = described_class.adapt({ "dlcType" => "Bundle" }) - expect(adapted_data[:item_type]).to eq :dlc_bundle + expect(adapted_data[:item_type]).to eq ItemTypes::DLC_BUNDLE end end context "when dlcType is ROM Bundle" do - it "returns :game_bundle" do + it "returns ItemTypes::GAME_BUNDLE" do adapted_data = described_class.adapt({ "dlcType" => "ROM Bundle" }) - expect(adapted_data[:item_type]).to eq :game_bundle + expect(adapted_data[:item_type]).to eq ItemTypes::GAME_BUNDLE end end