Module: Spree::ProductDecorator

Defined in:
app/models/spree/product_decorator.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.prepended(base) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'app/models/spree/product_decorator.rb', line 3

def self.prepended(base)
  base.has_many :product_properties, dependent: :destroy, inverse_of: :product
  base.has_many :properties, through: :product_properties

  base.accepts_nested_attributes_for :product_properties, allow_destroy: true, reject_if: lambda { |pp|
    pp[:property_id].blank? || (pp[:id].blank? && pp[:value].blank?)
  }

  base.whitelisted_ransackable_associations |= %w[properties]

  # Property scopes
  base.add_search_scope :with_property do |property|
    joins(:properties).where(Spree::Product.property_conditions(property))
  end

  base.add_search_scope :with_property_value do |property, value|
    if Spree.use_translations?
      joins(:properties).
        join_translation_table(Spree::Property).
        join_translation_table(Spree::ProductProperty).
        where(Spree::ProductProperty.translation_table_alias => { value: value }).
        where(Spree::Product.property_conditions(property))
    else
      joins(:properties).
        where(Spree::ProductProperty.table_name => { value: value }).
        where(Spree::Product.property_conditions(property))
    end
  end

  base.add_search_scope :with_property_values do |property_filter_param, property_values|
    joins(product_properties: :property).
      where(Spree::Property.table_name => { filter_param: property_filter_param }).
      where(Spree::ProductProperty.table_name => { filter_param: property_values.map(&:parameterize) })
  end
end

.property_conditions(property) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/models/spree/product_decorator.rb', line 39

def self.property_conditions(property)
  properties_table = Spree::Property.table_name

  case property
  when Spree::Property then { "#{properties_table}.id" => property.id }
  when Integer then { "#{properties_table}.id" => property }
  else
    if Spree::Property.column_for_attribute('id').type == :uuid
      ["#{properties_table}.name = ? OR #{properties_table}.id = ?", property, property]
    else
      { "#{properties_table}.name" => property }
    end
  end
end

Instance Method Details

#property(property_name) ⇒ Object



54
55
56
57
58
59
60
# File 'app/models/spree/product_decorator.rb', line 54

def property(property_name)
  if product_properties.loaded?
    product_properties.detect { |pp| pp.property.name == property_name }.try(:value)
  else
    product_properties.joins(:property).find_by(spree_properties: { name: property_name }).try(:value)
  end
end

#remove_property(property_name) ⇒ Object



85
86
87
# File 'app/models/spree/product_decorator.rb', line 85

def remove_property(property_name)
  product_properties.joins(:property).find_by(spree_properties: { name: property_name.parameterize })&.destroy
end

#set_property(property_name, property_value, property_presentation = property_name) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/models/spree/product_decorator.rb', line 62

def set_property(property_name, property_value, property_presentation = property_name)
  property_name = property_name.to_s.parameterize
  ApplicationRecord.transaction do
    prop = if Spree::Property.where(name: property_name).exists?
             existing_property = Spree::Property.where(name: property_name).first
             existing_property.presentation ||= property_presentation
             existing_property.save
             existing_property
           else
             Spree::Property.create(name: property_name, presentation: property_presentation)
           end

    product_property = if Spree::ProductProperty.where(product: self, property: prop).exists?
                         Spree::ProductProperty.where(product: self, property: prop).first
                       else
                         Spree::ProductProperty.new(product: self, property: prop)
                       end

    product_property.value = property_value
    product_property.save!
  end
end

#storefront_descriptionObject



89
90
91
# File 'app/models/spree/product_decorator.rb', line 89

def storefront_description
  property('short_description') || description
end