Class: Spree::Taxon

Inherits:
Object
  • Object
show all
Extended by:
FriendlyId
Includes:
PgSearch::Model, MemoizedData, Metadata, Metafields, TranslatableResource, TranslatableResourceSlug
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



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

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

Instance Method Details

#active_productsObject



356
357
358
359
# File 'app/models/spree/taxon.rb', line 356

def active_products
  Spree::Deprecation.warn('active_products is deprecated and will be removed in Spree 5.5. Please use taxon.products.active instead.')
  products.active
end

#active_products_with_descendantsObject



162
163
164
165
166
167
168
169
170
171
# File 'app/models/spree/taxon.rb', line 162

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



314
315
316
317
318
319
320
321
322
323
# File 'app/models/spree/taxon.rb', line 314

def applicable_filters
  Spree::Deprecation.warn('applicable_filters is deprecated and will be removed in Spree 5.5')
  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



377
378
379
380
381
# File 'app/models/spree/taxon.rb', line 377

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.


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

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

#generate_pretty_nameObject



334
335
336
# File 'app/models/spree/taxon.rb', line 334

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

#generate_slugObject



338
339
340
341
342
343
344
345
346
# File 'app/models/spree/taxon.rb', line 338

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:



154
155
156
# File 'app/models/spree/taxon.rb', line 154

def manual?
  !automatic?
end

#manual_sort_order?Boolean

Returns:



158
159
160
# File 'app/models/spree/taxon.rb', line 158

def manual_sort_order?
  sort_order == 'manual'
end

#products_matching_rules(opts = {}) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'app/models/spree/taxon.rb', line 173

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


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

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


369
370
371
372
373
374
375
# File 'app/models/spree/taxon.rb', line 369

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



211
212
213
214
215
216
# File 'app/models/spree/taxon.rb', line 211

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



326
327
328
# File 'app/models/spree/taxon.rb', line 326

def seo_title
  meta_title.blank? ? name : meta_title
end


348
349
350
351
352
353
354
# File 'app/models/spree/taxon.rb', line 348

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

#set_pretty_nameObject



330
331
332
# File 'app/models/spree/taxon.rb', line 330

def set_pretty_name
  self.pretty_name = generate_pretty_name
end

#slugObject



218
219
220
# File 'app/models/spree/taxon.rb', line 218

def slug
  permalink
end

#slug=(value) ⇒ Object



222
223
224
# File 'app/models/spree/taxon.rb', line 222

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