Class: Spree::Taxon

Inherits:
Object
  • Object
show all
Extended by:
FriendlyId
Includes:
PgSearch::Model, Linkable, MemoizedData, Metadata, Metafields, TranslatableResource, TranslatableResourceSlug, Webhooks::HasWebhooks
Defined in:
app/models/spree/taxon.rb

Constant Summary collapse

RULES_MATCH_POLICIES =
%w[all any].freeze
SORT_ORDERS =
%w[
  manual
  best-selling
  name-a-z
  name-z-a
  price-high-to-low
  price-low-to-high
  newest-first
  oldest-first
]
MEMOIZED_METHODS =
%w[cached_self_and_descendants_ids].freeze
TRANSLATABLE_FIELDS =

Translations

%i[name pretty_name description permalink].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.search_by_name(query) ⇒ Object



116
117
118
# File 'app/models/spree/taxon.rb', line 116

def self.search_by_name(query)
  i18n { name.lower.matches("%#{query.downcase}%") }
end

Instance Method Details

#active_productsObject



368
369
370
# File 'app/models/spree/taxon.rb', line 368

def active_products
  products.active
end

#active_products_with_descendantsObject



174
175
176
177
178
179
180
181
182
183
# File 'app/models/spree/taxon.rb', line 174

def active_products_with_descendants
  @active_products_with_descendants ||= store.products.
                                        joins(:classifications).
                                        active.
                                        where(
                                          Spree::Classification.table_name => {
                                            taxon_id: descendants.ids + [id]
                                          }
                                        )
end

#applicable_filtersObject

indicate which filters should be used for a taxon this method should be customized to your own site



326
327
328
329
330
331
332
333
334
335
# File 'app/models/spree/taxon.rb', line 326

def applicable_filters
  Spree::Deprecation.warn('applicable_filters is deprecated and will be removed in Spree 6.0')
  fs = []
  # fs << ProductFilters.taxons_below(self)
  ## unless it's a root taxon? left open for demo purposes

  fs << Spree::Core::ProductFilters.price_filter if Spree::Core::ProductFilters.respond_to?(:price_filter)
  fs << Spree::Core::ProductFilters.brand_filter if Spree::Core::ProductFilters.respond_to?(:brand_filter)
  fs
end

#cached_self_and_descendants_idsObject



388
389
390
391
392
# File 'app/models/spree/taxon.rb', line 388

def cached_self_and_descendants_ids
  @cached_self_and_descendants_ids ||= Rails.cache.fetch("#{cache_key_with_version}/descendant-ids") do
    self_and_descendants.ids
  end
end

#child_index=(idx) ⇒ Object

awesome_nested_set sorts by :lft and :rgt. This call re-inserts the child node so that its resulting position matches the observable 0-indexed position. ** Note ** no :position column needed - a_n_s doesn’t handle the reordering if

you bring your own :order_column.

See #3390 for background.


400
401
402
# File 'app/models/spree/taxon.rb', line 400

def child_index=(idx)
  move_to_child_with_index(parent, idx.to_i) unless new_record?
end

#featured?Boolean

Returns:



410
411
412
# File 'app/models/spree/taxon.rb', line 410

def featured?
  featured_sections.any?
end


414
415
416
# File 'app/models/spree/taxon.rb', line 414

def featured_sections
  @featured_sections ||= Spree::PageSections::FeaturedTaxon.published.by_taxon_id(id)
end

#generate_pretty_nameObject



346
347
348
# File 'app/models/spree/taxon.rb', line 346

def generate_pretty_name
  [parent&.pretty_name, name].compact.join(' -> ')
end

#generate_slugObject



350
351
352
353
354
355
356
357
358
# File 'app/models/spree/taxon.rb', line 350

def generate_slug
  if parent.present?
    [parent.permalink, (permalink.blank? ? name.to_url : permalink.split('/').last.to_url)].join('/')
  elsif permalink.blank?
    name.to_url
  else
    permalink.to_url
  end
end

#manual?Boolean

Returns:



162
163
164
# File 'app/models/spree/taxon.rb', line 162

def manual?
  !automatic?
end

#manual_sort_order?Boolean

Returns:



166
167
168
# File 'app/models/spree/taxon.rb', line 166

def manual_sort_order?
  sort_order == 'manual'
end

#page_builder_imageObject



170
171
172
# File 'app/models/spree/taxon.rb', line 170

def page_builder_image
  square_image.presence || image
end

#page_builder_urlObject



404
405
406
407
408
# File 'app/models/spree/taxon.rb', line 404

def page_builder_url
  return unless Spree::Core::Engine.routes.url_helpers.respond_to?(:nested_taxons_path)

  Spree::Core::Engine.routes.url_helpers.nested_taxons_path(self)
end

#products_matching_rules(opts = {}) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'app/models/spree/taxon.rb', line 185

def products_matching_rules(opts = {})
  return Spree::Product.none if manual? || rules.empty?

  storefront = opts[:storefront] || false
  currency = opts[:currency] || store.default_currency

  all_products = store.products.not_archived

  products_matcher_cache_key = [
    'products_matching_rules',
    cache_key_with_version,
    storefront,
    currency,
    all_products.cache_key_with_version
  ]

  all_products = all_products.active(currency: currency) if storefront

  any_rules_match_policy = rules_match_policy == 'any'
  products = any_rules_match_policy ? Spree::Product.none : all_products

  rules.each do |rule|
    if any_rules_match_policy
      product_ids = rule.apply(all_products).ids
      # it's safer to use this approach with ids as it will not break if the rule is not a simple where clause
      # and we will avoid `ArgumentError (Relation passed to #or must be structurally compatible. Incompatible values: [:group, :order, :joins, :readonly])` error
      products = products.or(all_products.where(id: product_ids)) if product_ids.any?
    else
      products = rule.apply(products)
    end
  end

  products
end


372
373
374
375
376
377
378
# File 'app/models/spree/taxon.rb', line 372

def regenerate_pretty_name_and_permalink
  Mobility.with_locale(nil) do
    update_columns(pretty_name: generate_pretty_name, permalink: generate_slug, updated_at: Time.current)
  end

  children.reload.each(&:regenerate_pretty_name_and_permalink_as_child)
end


380
381
382
383
384
385
386
# File 'app/models/spree/taxon.rb', line 380

def regenerate_pretty_name_and_permalink_as_child
  Mobility.with_locale(nil) do
    update_columns(pretty_name: generate_pretty_name, permalink: generate_slug, updated_at: Time.current)
  end

  children.reload.each(&:regenerate_pretty_name_and_permalink_as_child)
end

#regenerate_taxon_products(only_once: false) ⇒ Object

we need to create a new taxon product (classification) record for each product that matches the rules so we can later use them for product filtering and so on if we want to fire the service once during object lifecycle - pass only_once: true



223
224
225
226
227
228
# File 'app/models/spree/taxon.rb', line 223

def regenerate_taxon_products(only_once: false)
  if marked_for_regenerate_taxon_products?
    Spree::Taxons::RegenerateProducts.call(taxon: self)
    self.marked_for_regenerate_taxon_products = false if !frozen? && only_once
  end
end

#seo_titleObject

Return meta_title if set otherwise generates from taxon name



338
339
340
# File 'app/models/spree/taxon.rb', line 338

def seo_title
  meta_title.blank? ? name : meta_title
end


360
361
362
363
364
365
366
# File 'app/models/spree/taxon.rb', line 360

def set_permalink
  if Spree.use_translations?
    translations.each(&:set_permalink)
  else
    self.permalink = generate_slug
  end
end

#set_pretty_nameObject



342
343
344
# File 'app/models/spree/taxon.rb', line 342

def set_pretty_name
  self.pretty_name = generate_pretty_name
end

#slugObject



230
231
232
# File 'app/models/spree/taxon.rb', line 230

def slug
  permalink
end

#slug=(value) ⇒ Object



234
235
236
# File 'app/models/spree/taxon.rb', line 234

def slug=(value)
  self.permalink = value
end