Class: Spree::Product
- Extended by:
- FriendlyId
- Includes:
- Scopes, SoftDeletable
- Defined in:
- app/models/spree/product.rb,
app/models/spree/product/scopes.rb
Overview
Products represent an entity for sale in a store. Products can have variations, called variants. Product properties include description, permalink, availability, shipping category, etc. that do not change by variant.
Defined Under Namespace
Modules: Scopes
Constant Summary collapse
- MASTER_ATTRIBUTES =
[ :cost_currency, :cost_price, :depth, :height, :price, :sku, :track_inventory, :weight, :width, :gtin, :condition ]
Instance Attribute Summary collapse
-
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
Class Method Summary collapse
-
.like_any(fields, values) ⇒ ActiveRecord::Relation
Poor man’s full text search.
Instance Method Summary collapse
-
#available? ⇒ Boolean
Determines if product is available.
- #brand ⇒ Object
-
#deleted? ⇒ Boolean
Use for checking whether this product has been deleted.
-
#discontinued? ⇒ Boolean
Determines if product is discontinued.
-
#duplicate ⇒ Spree::Product
Creates a new product with the same attributes, variants, etc.
-
#empty_option_values? ⇒ Boolean
True if there are no option values.
-
#ensure_option_types_exist_for_values_hash ⇒ Array
Ensures option_types and product_option_types exist for keys in option_values_hash.
- #find_or_build_master ⇒ Object
-
#find_variant_property_rule(option_value_ids) ⇒ Spree::VariantPropertyRule
Finds the variant property rule that matches the provided option value ids.
-
#gallery ⇒ Spree::Gallery
The gallery for the product, which represents all the images associated with it, including those on its variants.
-
#has_variants? ⇒ Boolean
True if there are any variants.
-
#possible_promotions ⇒ Array
All advertised and not-rejected promotions.
-
#property(property_name) ⇒ String
The value of the given property.
-
#set_property(property_name, property_value) ⇒ Object
Assigns the given value to the given property.
-
#tax_category ⇒ Spree::TaxCategory
Tax category for this product, or the default tax category.
-
#tax_category_id ⇒ Integer
Tax category id for this product, or the default tax category id.
-
#total_on_hand ⇒ Fixnum, Infinity
The number of on-hand stock items; Infinity if any variant does not track inventory.
-
#variant_option_values_by_option_type(variant_scope = nil) ⇒ Hash<Spree::OptionType, Array<Spree::OptionValue>>
Groups all of the option values that are associated to the product’s variants, grouped by option type.
-
#variants_and_option_values_for(pricing_options = Spree::Config.default_pricing_options) ⇒ Array<Spree::Variant>
All variants with at least one option value.
Methods included from Scopes
Methods inherited from Base
Methods included from Core::Permalinks
#generate_permalink, #save_permalink
Instance Attribute Details
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
130 131 132 |
# File 'app/models/spree/product.rb', line 130 def option_values_hash @option_values_hash end |
Class Method Details
.like_any(fields, values) ⇒ ActiveRecord::Relation
Poor man’s full text search.
Filters products to those which have any of the strings in values in any of the fields in fields.
209 210 211 212 213 214 |
# File 'app/models/spree/product.rb', line 209 def self.like_any(fields, values) conditions = fields.product(values).map do |(field, value)| arel_table[field].matches("%#{value}%") end where conditions.inject(:or) end |
Instance Method Details
#available? ⇒ Boolean
Determines if product is available. A product is available if it has not been deleted, the available_on date is in the past and the discontinue_on date is nil or in the future.
187 188 189 |
# File 'app/models/spree/product.rb', line 187 def available? !deleted? && available_on&.past? && !discontinued? end |
#brand ⇒ Object
302 303 304 |
# File 'app/models/spree/product.rb', line 302 def brand Spree::Config.brand_selector_class.new(self).call end |
#deleted? ⇒ Boolean
Use for checking whether this product has been deleted. Provided for overriding the logic for determining if a product is deleted.
178 179 180 |
# File 'app/models/spree/product.rb', line 178 def deleted? !!deleted_at end |
#discontinued? ⇒ Boolean
Determines if product is discontinued.
A product is discontinued if the discontinue_on date is not nil and in the past.
197 198 199 |
# File 'app/models/spree/product.rb', line 197 def discontinued? !!discontinue_on&.past? end |
#duplicate ⇒ Spree::Product
Creates a new product with the same attributes, variants, etc.
169 170 171 172 |
# File 'app/models/spree/product.rb', line 169 def duplicate duplicator = ProductDuplicator.new(self) duplicator.duplicate end |
#empty_option_values? ⇒ Boolean
Returns true if there are no option values.
244 245 246 |
# File 'app/models/spree/product.rb', line 244 def empty_option_values? .empty? || !option_types.left_joins(:option_values).where("spree_option_values.id IS NULL").empty? end |
#ensure_option_types_exist_for_values_hash ⇒ Array
Ensures option_types and product_option_types exist for keys in option_values_hash.
160 161 162 163 164 |
# File 'app/models/spree/product.rb', line 160 def ensure_option_types_exist_for_values_hash return if option_values_hash.nil? required_option_type_ids = option_values_hash.keys.map(&:to_i) self.option_type_ids |= required_option_type_ids end |
#find_or_build_master ⇒ Object
77 78 79 |
# File 'app/models/spree/product.rb', line 77 def find_or_build_master master || build_master end |
#find_variant_property_rule(option_value_ids) ⇒ Spree::VariantPropertyRule
Finds the variant property rule that matches the provided option value ids.
288 289 290 291 292 |
# File 'app/models/spree/product.rb', line 288 def find_variant_property_rule(option_value_ids) variant_property_rules.find do |rule| rule.matches_option_value_ids?(option_value_ids) end end |
#gallery ⇒ Spree::Gallery
The gallery for the product, which represents all the images associated with it, including those on its variants
298 299 300 |
# File 'app/models/spree/product.rb', line 298 def gallery @gallery ||= Spree::Config.product_gallery_class.new(self) end |
#has_variants? ⇒ Boolean
Returns true if there are any variants.
142 143 144 |
# File 'app/models/spree/product.rb', line 142 def has_variants? variants.any? end |
#possible_promotions ⇒ Array
Returns all advertised and not-rejected promotions.
270 271 272 |
# File 'app/models/spree/product.rb', line 270 def possible_promotions Spree::Config.promotions.advertiser_class.for_product(self) end |
#property(property_name) ⇒ String
Returns the value of the given property. nil if property is undefined on this product.
250 251 252 253 |
# File 'app/models/spree/product.rb', line 250 def property(property_name) return nil unless (prop = properties.find_by(name: property_name)) product_properties.find_by(property: prop).try(:value) end |
#set_property(property_name, property_value) ⇒ Object
Assigns the given value to the given property.
259 260 261 262 263 264 265 266 267 |
# File 'app/models/spree/product.rb', line 259 def set_property(property_name, property_value) ActiveRecord::Base.transaction do # Works around spree_i18n https://github.com/spree/spree/issues/301 property = Spree::Property.create_with(presentation: property_name).find_or_create_by(name: property_name) product_property = Spree::ProductProperty.where(product: self, property:).first_or_initialize product_property.value = property_value product_property.save! end end |
#tax_category ⇒ Spree::TaxCategory
Returns tax category for this product, or the default tax category.
147 148 149 |
# File 'app/models/spree/product.rb', line 147 def tax_category super || Spree::TaxCategory.find_by(is_default: true) end |
#tax_category_id ⇒ Integer
Returns tax category id for this product, or the default tax category id.
152 153 154 |
# File 'app/models/spree/product.rb', line 152 def tax_category_id super || tax_category&.id end |
#total_on_hand ⇒ Fixnum, Infinity
The number of on-hand stock items; Infinity if any variant does not track inventory.
278 279 280 281 282 |
# File 'app/models/spree/product.rb', line 278 def total_on_hand variants_including_master.sum do |variant| Spree::Config.stock.quantifier_class.new(variant).total_on_hand end end |
#variant_option_values_by_option_type(variant_scope = nil) ⇒ Hash<Spree::OptionType, Array<Spree::OptionValue>>
Groups all of the option values that are associated to the product’s variants, grouped by option type.
used to determine the applied option_types associated with the products variants grouped by option type
232 233 234 235 236 237 238 239 240 241 |
# File 'app/models/spree/product.rb', line 232 def variant_option_values_by_option_type(variant_scope = nil) option_value_scope = Spree::OptionValuesVariant.joins(:variant) .where(spree_variants: {product_id: id}) option_value_scope = option_value_scope.merge(variant_scope) if variant_scope option_value_ids = option_value_scope.distinct.pluck(:option_value_id) Spree::OptionValue.where(id: option_value_ids) .includes(:option_type) .order("#{Spree::OptionType.table_name}.position, #{Spree::OptionValue.table_name}.position") .group_by(&:option_type) end |
#variants_and_option_values_for(pricing_options = Spree::Config.default_pricing_options) ⇒ Array<Spree::Variant>
Returns all variants with at least one option value.
219 220 221 222 223 |
# File 'app/models/spree/product.rb', line 219 def variants_and_option_values_for( = Spree::Config.) variants.includes(:option_values).with_prices().select do |variant| variant.option_values.any? end end |