Class: Spree::Taxon
Constant Summary
collapse
- RULES_MATCH_POLICIES =
%w[all any].freeze
- SORT_ORDERS =
[
'manual',
'best_selling',
'price asc',
'price desc',
'available_on desc',
'available_on asc',
'name asc',
'name desc'
].freeze
- MEMOIZED_METHODS =
%w[cached_self_and_descendants_ids].freeze
- TRANSLATABLE_FIELDS =
%i[name pretty_name description permalink].freeze
- RICH_TEXT_TRANSLATABLE_FIELDS =
%i[description].freeze
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Metadata
#metadata, #metadata=, #public_metadata=
#get_field_with_locale, #translatable_store, #upsert_translations
Class Method Details
.recalculate_products_count(taxon_ids) ⇒ Object
Recomputes the stored, descendant-inclusive products_count for the given
taxons AND all of their ancestors — the nodes whose inclusive count can
shift when a classification changes. Counts unique products classified
under each node or its descendants (a product reachable through several
nodes is counted once per ancestor). Call after any classification change.
220
221
222
223
224
225
226
227
228
229
230
231
|
# File 'app/models/spree/taxon.rb', line 220
def self.recalculate_products_count(taxon_ids)
changed = unscoped.where(id: Array(taxon_ids).compact.uniq)
affected = changed.flat_map { |taxon| taxon.self_and_ancestors.to_a }.uniq(&:id)
affected.each do |taxon|
count = Spree::Classification.where(taxon_id: taxon.self_and_descendants.select(:id))
.distinct.count(:product_id)
taxon.update_column(:products_count, count) if taxon.products_count != count
end
end
|
.search_by_name(query) ⇒ Object
133
134
135
|
# File 'app/models/spree/taxon.rb', line 133
def self.search_by_name(query)
i18n { name.lower.matches("%#{query.downcase}%") }
end
|
Instance Method Details
#active_products_with_descendants ⇒ Object
202
203
204
205
206
207
208
209
210
211
|
# File 'app/models/spree/taxon.rb', line 202
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
|
#cached_self_and_descendants_ids ⇒ Object
420
421
422
423
424
|
# File 'app/models/spree/taxon.rb', line 420
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.
432
433
434
|
# File 'app/models/spree/taxon.rb', line 432
def child_index=(idx)
move_to_child_with_index(parent, idx.to_i) unless new_record?
end
|
#generate_pretty_name ⇒ Object
382
383
384
|
# File 'app/models/spree/taxon.rb', line 382
def generate_pretty_name
[parent&.pretty_name, name].compact.join(' -> ')
end
|
#generate_slug ⇒ Object
386
387
388
389
390
391
392
393
394
|
# File 'app/models/spree/taxon.rb', line 386
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
|
182
183
184
|
# File 'app/models/spree/taxon.rb', line 182
def manual?
!automatic?
end
|
#manual_sort_order? ⇒ Boolean
198
199
200
|
# File 'app/models/spree/taxon.rb', line 198
def manual_sort_order?
sort_order == 'manual'
end
|
#products_matching_rules(opts = {}) ⇒ Object
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
|
# File 'app/models/spree/taxon.rb', line 233
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
products = products.or(all_products.where(id: product_ids)) if product_ids.any?
else
products = rule.apply(products)
end
end
products
end
|
#regenerate_pretty_name_and_permalink ⇒ Object
404
405
406
407
408
409
410
|
# File 'app/models/spree/taxon.rb', line 404
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
|
#regenerate_pretty_name_and_permalink_as_child ⇒ Object
412
413
414
415
416
417
418
|
# File 'app/models/spree/taxon.rb', line 412
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
271
272
273
274
275
276
|
# File 'app/models/spree/taxon.rb', line 271
def regenerate_taxon_products(only_once: false)
return unless marked_for_regenerate_taxon_products?
Spree::Taxons::RegenerateProducts.call(taxon: self)
self.marked_for_regenerate_taxon_products = false if !frozen? && only_once
end
|
#requires_taxonomy? ⇒ Boolean
Whether a taxonomy is mandatory. Legacy Spree::Taxon requires one;
Spree::Category overrides this to false (it is owned via store_id).
194
195
196
|
# File 'app/models/spree/taxon.rb', line 194
def requires_taxonomy?
true
end
|
#seo_title ⇒ Object
Return meta_title if set otherwise generates from taxon name
374
375
376
|
# File 'app/models/spree/taxon.rb', line 374
def seo_title
meta_title.blank? ? name : meta_title
end
|
#set_permalink ⇒ Object
396
397
398
399
400
401
402
|
# File 'app/models/spree/taxon.rb', line 396
def set_permalink
if Spree.use_translations?
translations.each(&:set_permalink)
else
self.permalink = generate_slug
end
end
|
#set_pretty_name ⇒ Object
378
379
380
|
# File 'app/models/spree/taxon.rb', line 378
def set_pretty_name
self.pretty_name = generate_pretty_name
end
|
#slug ⇒ Object
278
279
280
|
# File 'app/models/spree/taxon.rb', line 278
def slug
permalink
end
|
#slug=(value) ⇒ Object
282
283
284
|
# File 'app/models/spree/taxon.rb', line 282
def slug=(value)
self.permalink = value
end
|
#store ⇒ Object
The owning store. Prefers the direct store_id; falls back to the
taxonomy's store for legacy rows not yet backfilled.
188
189
190
|
# File 'app/models/spree/taxon.rb', line 188
def store
super || taxonomy&.store
end
|