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

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

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::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#brandString

Returns:

  • (String)


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

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

#countryString

Returns:

  • (String)


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

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

#localeString

Returns:

  • (String)


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

validates :locale, presence: true

#schemaHash

Returns:

  • (Hash)


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

validates :schema, presence: true

#taxonomy_category_idInteger

Returns:

  • (Integer)

Validations:

  • Uniqueness ({ scope: %i[brand country locale] })


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

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:



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

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:



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

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:



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

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:



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

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



104
105
106
# File 'app/models/wayfair_schema.rb', line 104

def attribute_ids
  attributes_list.pluck('taxonomyAttributeId')
end

#attribute_titlesArray<String>

Get attribute names/titles

Returns:

  • (Array<String>)

    Array of attribute titles



98
99
100
# File 'app/models/wayfair_schema.rb', line 98

def attribute_titles
  attributes_list.pluck('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



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/models/wayfair_schema.rb', line 65

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



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/models/wayfair_schema.rb', line 82

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')



163
164
165
166
# File 'app/models/wayfair_schema.rb', line 163

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



111
112
113
# File 'app/models/wayfair_schema.rb', line 111

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



118
119
120
# File 'app/models/wayfair_schema.rb', line 118

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



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

def optional_attributes
  attributes_list.reject { |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



137
138
139
140
141
142
# File 'app/models/wayfair_schema.rb', line 137

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

  (attr['possibleAttributeValues'] || []).pluck('value')
end

#refresh_schema(orchestrator = nil) ⇒ Object

Refresh schema from Wayfair API

Parameters:



170
171
172
173
174
175
176
177
178
179
# File 'app/models/wayfair_schema.rb', line 170

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



124
125
126
# File 'app/models/wayfair_schema.rb', line 124

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

#schema_ageObject

Schema age in human-readable format



182
183
184
# File 'app/models/wayfair_schema.rb', line 182

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

#schema_as_jsonObject

Schema as pretty JSON for display



187
188
189
190
191
# File 'app/models/wayfair_schema.rb', line 187

def schema_as_json
  return if schema.blank?

  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)


148
149
150
151
152
153
154
155
156
157
158
# File 'app/models/wayfair_schema.rb', line 148

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