Class: Spree::Product
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Spree::Product
- Defined in:
- app/models/spree/product.rb,
app/models/spree/product/scopes.rb
Instance Attribute Summary collapse
-
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
-
#prototype_id ⇒ Object
Adding properties and option types on creation based on a chosen prototype.
Class Method Summary collapse
- .add_search_scope(name, &block) ⇒ Object
-
.available(available_on = nil) ⇒ Object
Can’t use add_search_scope for this as it needs a default argument.
- .like_any(fields, values) ⇒ Object
- .simple_scopes ⇒ Object
Instance Method Summary collapse
-
#categorise_variants_from_option(opt_type) ⇒ Object
split variants list into hash which shows mapping of opt value onto matching variants eg categorise_variants_from_option(color) => -> […], “blue” -> […].
-
#deleted? ⇒ Boolean
use deleted? rather than checking the attribute directly.
-
#duplicate ⇒ Object
for adding products which are closely related to existing ones define “duplicate_extra” for site-specific actions, eg for additional fields.
- #empty_option_values? ⇒ Boolean
- #ensure_master ⇒ Object
-
#ensure_option_types_exist_for_values_hash ⇒ Object
Ensures option_types and product_option_types exist for keys in option_values_hash.
-
#has_stock? ⇒ Boolean
Returns true if there are inventory units (any variant) with “on_hand” state for this product.
-
#has_variants? ⇒ Boolean
returns true if the product has any variants (the master variant is not a member of the variants array).
-
#on_hand ⇒ Object
returns the number of inventory units “on_hand” for this product.
-
#on_hand=(new_level) ⇒ Object
adjusts the “on_hand” inventory level for the product up or down to match the given new_level.
- #property(property_name) ⇒ Object
- #set_property(property_name, property_value) ⇒ Object
- #tax_category ⇒ Object
- #to_param ⇒ Object
- #variant_images ⇒ Object (also: #images)
Instance Attribute Details
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
72 73 74 |
# File 'app/models/spree/product.rb', line 72 def option_values_hash @option_values_hash end |
#prototype_id ⇒ Object
Adding properties and option types on creation based on a chosen prototype
130 131 132 |
# File 'app/models/spree/product.rb', line 130 def prototype_id @prototype_id end |
Class Method Details
.add_search_scope(name, &block) ⇒ Object
7 8 9 10 |
# File 'app/models/spree/product/scopes.rb', line 7 def self.add_search_scope(name, &block) self.singleton_class.send(:define_method, name.to_sym, &block) search_scopes << name.to_sym end |
.available(available_on = nil) ⇒ Object
Can’t use add_search_scope for this as it needs a default argument
191 192 193 |
# File 'app/models/spree/product/scopes.rb', line 191 def self.available(available_on = nil) where("#{Product.quoted_table_name}.available_on <= ?", available_on || Time.now) end |
.like_any(fields, values) ⇒ Object
186 187 188 189 |
# File 'app/models/spree/product.rb', line 186 def self.like_any(fields, values) where_str = fields.map { |field| Array.new(values.size, "#{self.quoted_table_name}.#{field} #{LIKE} ?").join(' OR ') }.join(' OR ') self.where([where_str, values.map { |value| "%#{value}%" } * fields.size].flatten) end |
.simple_scopes ⇒ Object
12 13 14 15 16 17 18 19 |
# File 'app/models/spree/product/scopes.rb', line 12 def self.simple_scopes [ :ascend_by_updated_at, :descend_by_updated_at, :ascend_by_name, :descend_by_name ] end |
Instance Method Details
#categorise_variants_from_option(opt_type) ⇒ Object
split variants list into hash which shows mapping of opt value onto matching variants eg categorise_variants_from_option(color) => -> […], “blue” -> […]
181 182 183 184 |
# File 'app/models/spree/product.rb', line 181 def categorise_variants_from_option(opt_type) return {} unless option_types.include?(opt_type) variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type} } end |
#deleted? ⇒ Boolean
use deleted? rather than checking the attribute directly. this allows extensions to override deleted? if they want to provide their own definition.
175 176 177 |
# File 'app/models/spree/product.rb', line 175 def deleted? !!deleted_at end |
#duplicate ⇒ Object
for adding products which are closely related to existing ones define “duplicate_extra” for site-specific actions, eg for additional fields
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'app/models/spree/product.rb', line 146 def duplicate p = self.dup p.name = 'COPY OF ' + name p.deleted_at = nil p.created_at = p.updated_at = nil p.taxons = taxons p.product_properties = product_properties.map { |q| r = q.dup; r.created_at = r.updated_at = nil; r } image_dup = lambda { |i| j = i.dup; j. = i..clone; j } variant = master.dup variant.sku = 'COPY OF ' + master.sku variant.deleted_at = nil variant.images = master.images.map { |i| image_dup.call i } p.master = variant # don't dup the actual variants, just the characterising types p.option_types = option_types if has_variants? # allow site to do some customization p.send(:duplicate_extra, self) if p.respond_to?(:duplicate_extra) p.save! p end |
#empty_option_values? ⇒ Boolean
191 192 193 194 195 |
# File 'app/models/spree/product.rb', line 191 def empty_option_values? .empty? || .any? do |opt| opt.option_type.option_values.empty? end end |
#ensure_master ⇒ Object
91 92 93 94 |
# File 'app/models/spree/product.rb', line 91 def ensure_master return unless new_record? self.master ||= Variant.new end |
#ensure_option_types_exist_for_values_hash ⇒ Object
Ensures option_types and product_option_types exist for keys in option_values_hash
136 137 138 139 140 141 142 |
# File 'app/models/spree/product.rb', line 136 def ensure_option_types_exist_for_values_hash return if option_values_hash.nil? option_values_hash.keys.map(&:to_i).each do |id| self.option_type_ids << id unless option_type_ids.include?(id) product_option_types.create({:option_type_id => id}, :without_protection => true) unless product_option_types.map(&:option_type_id).include?(id) end end |
#has_stock? ⇒ Boolean
Returns true if there are inventory units (any variant) with “on_hand” state for this product
117 118 119 |
# File 'app/models/spree/product.rb', line 117 def has_stock? master.in_stock? || variants.any?(&:in_stock?) end |
#has_variants? ⇒ Boolean
returns true if the product has any variants (the master variant is not a member of the variants array)
101 102 103 |
# File 'app/models/spree/product.rb', line 101 def has_variants? variants.any? end |
#on_hand ⇒ Object
returns the number of inventory units “on_hand” for this product
106 107 108 |
# File 'app/models/spree/product.rb', line 106 def on_hand has_variants? ? variants.inject(0) { |sum, v| sum + v.on_hand } : master.on_hand end |
#on_hand=(new_level) ⇒ Object
adjusts the “on_hand” inventory level for the product up or down to match the given new_level
111 112 113 114 |
# File 'app/models/spree/product.rb', line 111 def on_hand=(new_level) raise 'cannot set on_hand of product with variants' if has_variants? && Spree::Config[:track_inventory_levels] master.on_hand = new_level end |
#property(property_name) ⇒ Object
197 198 199 200 |
# File 'app/models/spree/product.rb', line 197 def property(property_name) return nil unless prop = properties.find_by_name(property_name) product_properties.find_by_property_id(prop.id).try(:value) end |
#set_property(property_name, property_value) ⇒ Object
202 203 204 205 206 207 208 209 210 211 |
# File 'app/models/spree/product.rb', line 202 def set_property(property_name, property_value) prop = Spree::Property.find_or_initialize_by_name(property_name) do |p| p.presentation = property_name p.save! end prod_prop = Spree::ProductProperty.find_or_initialize_by_product_id_and_property_id(self.id, prop.id) prod_prop.value = property_value prod_prop.save! end |
#tax_category ⇒ Object
121 122 123 124 125 126 127 |
# File 'app/models/spree/product.rb', line 121 def tax_category if self[:tax_category_id].nil? TaxCategory.where(:is_default => true).first else TaxCategory.find(self[:tax_category_id]) end end |
#to_param ⇒ Object
96 97 98 |
# File 'app/models/spree/product.rb', line 96 def to_param permalink.present? ? permalink : (permalink_was || name.to_s.to_url) end |
#variant_images ⇒ Object Also known as: images
61 62 63 64 65 66 |
# File 'app/models/spree/product.rb', line 61 def variant_images Image.joins("LEFT JOIN #{Variant.quoted_table_name} ON #{Variant.quoted_table_name}.id = #{Asset.quoted_table_name}.viewable_id"). where("#{Variant.quoted_table_name}.product_id = #{self.id}"). order("#{Asset.quoted_table_name}.position"). extend(Spree::Core::RelationSerialization) end |