Class: WayfairSchema

Inherits:
ApplicationRecord show all
Includes:
Models::Auditable
Defined in:
app/models/wayfair_schema.rb

Overview

== Schema Information

Table name: wayfair_schemas
Database name: primary

id :bigint not null, primary key
brand :string default("WAYFAIR"), not null
category_name :string
country :string default("UNITED_STATES"), not null
locale :string default("en-US"), not null
schema :jsonb not null
created_at :datetime not null
updated_at :datetime not null
taxonomy_category_id :integer not null

Indexes

idx_wayfair_schemas_on_taxonomy_market (taxonomy_category_id,brand,country,locale) UNIQUE

Constant Summary collapse

BRANDS =

Available Wayfair brands

%w[WAYFAIR ALLMODERN BIRCH_LANE JOSS_AND_MAIN PERIGOLD].freeze
COUNTRIES =

Available countries

%w[UNITED_STATES CANADA UNITED_KINGDOM GERMANY].freeze

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #creator, #should_not_save_version, #stamp_record, #updater

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#brandObject (readonly)



31
# File 'app/models/wayfair_schema.rb', line 31

validates :brand, presence: true, inclusion: { in: BRANDS }

#countryObject (readonly)



32
# File 'app/models/wayfair_schema.rb', line 32

validates :country, presence: true, inclusion: { in: COUNTRIES }

#localeObject (readonly)



33
# File 'app/models/wayfair_schema.rb', line 33

validates :locale, presence: true

#schemaObject (readonly)



34
# File 'app/models/wayfair_schema.rb', line 34

validates :schema, presence: true

#taxonomy_category_idObject (readonly)



30
# File 'app/models/wayfair_schema.rb', line 30

validates :taxonomy_category_id, presence: true

Class Method Details

.for_brandActiveRecord::Relation<WayfairSchema>

A relation of WayfairSchemas that are for brand. Active Record Scope

Returns:

See Also:



46
# File 'app/models/wayfair_schema.rb', line 46

scope :for_brand, ->(brand) { where(brand: brand.to_s.upcase) }

.for_categoryActiveRecord::Relation<WayfairSchema>

A relation of WayfairSchemas that are for category. Active Record Scope

Returns:

See Also:



45
# File 'app/models/wayfair_schema.rb', line 45

scope :for_category, ->(category_id) { where(taxonomy_category_id: category_id) }

.for_countryActiveRecord::Relation<WayfairSchema>

A relation of WayfairSchemas that are for country. Active Record Scope

Returns:

See Also:



47
# File 'app/models/wayfair_schema.rb', line 47

scope :for_country, ->(country) { where(country: country.to_s.upcase) }

.wayfair_usActiveRecord::Relation<WayfairSchema>

A relation of WayfairSchemas that are wayfair us. Active Record Scope

Returns:

See Also:



48
# File 'app/models/wayfair_schema.rb', line 48

scope :wayfair_us, -> { where(brand: 'WAYFAIR', country: 'UNITED_STATES') }

Instance Method Details

#attribute_idsArray<String>

Get attribute IDs

Returns:

  • (Array<String>)

    Array of taxonomy attribute IDs



94
95
96
# File 'app/models/wayfair_schema.rb', line 94

def attribute_ids
  attributes_list.map { |attr| attr['taxonomyAttributeId'] }
end

#attribute_titlesArray<String>

Get attribute names/titles

Returns:

  • (Array<String>)

    Array of attribute titles



88
89
90
# File 'app/models/wayfair_schema.rb', line 88

def attribute_titles
  attributes_list.map { |attr| attr['title'] }
end

#attributes_listArray<Hash>

Get all attributes from the schema
The schema can be:

  • An array (from attributesByFilter which returns [{ taxonomyCategoryId, attributes, conditionalityRules }])
  • A hash with 'attributes' key

Returns:

  • (Array<Hash>)

    Array of attribute definitions



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/models/wayfair_schema.rb', line 55

def attributes_list
  case schema
  when Array
    # attributesByFilter returns an array of results, take the first one's attributes
    first_element = schema.first
    return [] unless first_element.is_a?(Hash)

    fetch_with_indifferent_key(first_element, 'attributes', [])
  when Hash
    fetch_with_indifferent_key(schema, 'attributes', [])
  else
    []
  end
end

#conditionality_rulesArray<Hash>

Get the conditionality rules from the schema

Returns:

  • (Array<Hash>)

    Array of conditionality rules



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/models/wayfair_schema.rb', line 72

def conditionality_rules
  case schema
  when Array
    first_element = schema.first
    return [] unless first_element.is_a?(Hash)

    fetch_with_indifferent_key(first_element, 'conditionalityRules', [])
  when Hash
    fetch_with_indifferent_key(schema, 'conditionalityRules', [])
  else
    []
  end
end

#datatype_for(attribute_id) ⇒ String?

Get the datatype for an attribute

Parameters:

  • attribute_id (String, Integer)

    The taxonomy attribute ID

Returns:

  • (String, nil)

    The datatype (e.g., 'SINGLE_CHOICE', 'MULTI_CHOICE', 'STRING')



153
154
155
156
# File 'app/models/wayfair_schema.rb', line 153

def datatype_for(attribute_id)
  attr = find_attribute(attribute_id)
  attr&.dig('valueFormat', 'datatype')
end

#find_attribute(attribute_id) ⇒ Hash?

Find an attribute by its ID

Parameters:

  • attribute_id (String, Integer)

    The taxonomy attribute ID

Returns:

  • (Hash, nil)

    The attribute definition or nil



101
102
103
# File 'app/models/wayfair_schema.rb', line 101

def find_attribute(attribute_id)
  attributes_list.find { |attr| attr['taxonomyAttributeId'].to_s == attribute_id.to_s }
end

#find_attribute_by_title(title) ⇒ Hash?

Find an attribute by its title (case-insensitive)

Parameters:

  • title (String)

    The attribute title

Returns:

  • (Hash, nil)

    The attribute definition or nil



108
109
110
# File 'app/models/wayfair_schema.rb', line 108

def find_attribute_by_title(title)
  attributes_list.find { |attr| attr['title'].to_s.downcase == title.to_s.downcase }
end

#optional_attributesArray<Hash>

Get optional attributes only

Returns:

  • (Array<Hash>)

    Array of optional attribute definitions



120
121
122
# File 'app/models/wayfair_schema.rb', line 120

def optional_attributes
  attributes_list.select { |attr| attr['requirement'] != 'REQUIRED' }
end

#possible_values_for(attribute_id) ⇒ Array<String>

Get possible values for an attribute

Parameters:

  • attribute_id (String, Integer)

    The taxonomy attribute ID

Returns:

  • (Array<String>)

    Possible values or empty array



127
128
129
130
131
132
# File 'app/models/wayfair_schema.rb', line 127

def possible_values_for(attribute_id)
  attr = find_attribute(attribute_id)
  return [] unless attr

  (attr['possibleAttributeValues'] || []).map { |v| v['value'] }
end

#refresh_schema(orchestrator = nil) ⇒ Object

Refresh schema from Wayfair API

Parameters:



160
161
162
163
164
165
166
167
168
169
# File 'app/models/wayfair_schema.rb', line 160

def refresh_schema(orchestrator = nil)
  orchestrator ||= default_orchestrator
  orchestrator.pull_taxonomy_schema_for_category(
    taxonomy_category_id,
    brand: brand,
    country: country,
    locale: locale,
    wayfair_schema: self
  )
end

#required_attributesArray<Hash>

Get required attributes only

Returns:

  • (Array<Hash>)

    Array of required attribute definitions



114
115
116
# File 'app/models/wayfair_schema.rb', line 114

def required_attributes
  attributes_list.select { |attr| attr['requirement'] == 'REQUIRED' }
end

#schema_ageObject

Schema age in human-readable format



172
173
174
# File 'app/models/wayfair_schema.rb', line 172

def schema_age
  ActionController::Base.helpers.time_ago_in_words(updated_at)
end

#schema_as_jsonObject

Schema as pretty JSON for display



177
178
179
180
181
# File 'app/models/wayfair_schema.rb', line 177

def schema_as_json
  return unless schema.present?

  JSON.pretty_generate(JSON.parse(schema.to_json))
end

#valid_value?(attribute_id, value) ⇒ Boolean

Check if a value is valid for an attribute

Parameters:

  • attribute_id (String, Integer)

    The taxonomy attribute ID

  • value (String)

    The value to check

Returns:

  • (Boolean)


138
139
140
141
142
143
144
145
146
147
148
# File 'app/models/wayfair_schema.rb', line 138

def valid_value?(attribute_id, value)
  attr = find_attribute(attribute_id)
  return true unless attr

  # Check if custom values are allowed
  value_format = attr['valueFormat'] || {}
  return true if value_format['canValueBeCustomized']

  # Check against possible values
  possible_values_for(attribute_id).include?(value)
end