Class: Spree::Taxon

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

Direct Known Subclasses

Category

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 =

Translations

%i[name pretty_name description permalink].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Metadata

#metadata, #metadata=, #public_metadata=

Class Method Details

.search_by_name(query) ⇒ Object

Search



105
106
107
# File 'app/models/spree/taxon.rb', line 105

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

Instance Method Details

#active_productsObject



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

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



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

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_idsObject



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

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.


376
377
378
# File 'app/models/spree/taxon.rb', line 376

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

#generate_pretty_nameObject



321
322
323
# File 'app/models/spree/taxon.rb', line 321

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

#generate_slugObject



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

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:



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

def manual?
  !automatic?
end

#manual_sort_order?Boolean

Returns:



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

def manual_sort_order?
  sort_order == 'manual'
end

#products_matching_rules(opts = {}) ⇒ Object



172
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
# File 'app/models/spree/taxon.rb', line 172

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


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

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


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

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



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

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

#seo_titleObject

Return meta_title if set otherwise generates from taxon name



313
314
315
# File 'app/models/spree/taxon.rb', line 313

def seo_title
  meta_title.blank? ? name : meta_title
end


335
336
337
338
339
340
341
# File 'app/models/spree/taxon.rb', line 335

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

#set_pretty_nameObject



317
318
319
# File 'app/models/spree/taxon.rb', line 317

def set_pretty_name
  self.pretty_name = generate_pretty_name
end

#slugObject



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

def slug
  permalink
end

#slug=(value) ⇒ Object



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

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